home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / role / Ang261Lib.lha / src / creature.c < prev    next >
C/C++ Source or Header  |  1994-10-22  |  95KB  |  3,337 lines

  1. /*
  2.  * creature.c: handle monster movement and attacks 
  3.  *
  4.  * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke 
  5.  *
  6.  * This software may be copied and distributed for educational, research, and
  7.  * not for profit purposes provided that this copyright and statement are
  8.  * included in all such copies. 
  9.  */
  10.  
  11. #include "constant.h"
  12. #include "monster.h"
  13. #include "config.h"
  14. #include "types.h"
  15. #include "externs.h"
  16.  
  17. #ifdef USG
  18. #ifndef ATARIST_MWC
  19. #include <string.h>
  20. #else
  21. char *strcat();
  22. char *strcpy();
  23. #endif
  24. #else
  25. #include <strings.h>
  26. #endif
  27.  
  28. /* Lets do all prototypes correctly.... -CWS */
  29. #ifndef NO_LINT_ARGS
  30. #ifdef __STDC__
  31. static int  check_mon_lite(int, int);
  32. static void get_moves(int, int *);
  33. static int  monster_critical(int, int, int);
  34. static void make_attack(int);
  35. static void make_move(int, int *, int32u *);
  36. static void mon_cast_spell(int, int *);
  37. static void mon_move(int, int32u *);
  38. static void shatter_quake(int, int);
  39. static void br_wall(int, int);
  40. #else
  41. static int  check_mon_lite();
  42. static void get_moves();
  43. static int  monster_critical();
  44. static void make_attack();
  45. static void make_move();
  46. static void mon_cast_spell();
  47. static void mon_move();
  48. static void shatter_quake();
  49. static void br_wall();
  50. #endif
  51. #endif
  52.  
  53. /* Updates screen when monsters move about        -RAK-     */
  54. void 
  55. update_mon(monptr)
  56. int monptr;
  57. {
  58.     register int           flag;
  59.     register cave_type     *c_ptr;
  60.     register monster_type  *m_ptr;
  61.     register creature_type *r_ptr;
  62.  
  63. #ifdef ATARIST_MWC
  64.     int32u                 holder;
  65.  
  66. #endif
  67.  
  68.     m_ptr = &m_list[monptr];
  69.     flag = FALSE;
  70.     if ((m_ptr->cdis <= MAX_SIGHT) &&
  71.     (!(py.flags.status & PY_BLIND) || py.flags.telepathy) &&
  72.     (panel_contains((int)m_ptr->fy, (int)m_ptr->fx))) {
  73.     /* Wizard sight.         */
  74.     if (wizard)
  75.         flag = TRUE;
  76.  
  77.     /* if not mindless, telepathy sees -CWS */
  78.     if (py.flags.telepathy) {
  79.         char c = c_list[m_ptr->mptr].cchar;
  80.         const char *n = c_list[m_ptr->mptr].name;
  81.         if (strchr("EMXgjvz.",c));
  82.     /* don't show these ever (elementals & golems & vorticies & xorns
  83.      * "minds" are too different) -CFT */
  84.  
  85.         else if (strchr("FKaclt",c)) {
  86.         if (randint(5)==1)
  87.             flag = TRUE;
  88.     /* once in a while we see these almost mindless insects... -CFT */
  89.  
  90.         } else if (c=='S' && strncmp(n, "Drider", 6) &&
  91.              !(c_list[m_ptr->mptr].cdefense & UNIQUE)) {
  92.         if (randint(5)==1) flag = TRUE;
  93.     /* once in a while show spiders, scops.  But DO show drider,
  94.      * Shelob, and Ungol. -CFT */
  95.  
  96.         } else if (c=='m' && strncmp(n, "Death", 5));
  97.     /* don't show any molds, except the Death mold -CFT */
  98.  
  99.         else if (c=='s' && !strstr(n, "ruj") &&
  100.              strncmp(n, "Cantor", 6));
  101.     /* don't show skeletons, but DO show druj and Cantoras -CFT */
  102.  
  103.         else if (c=='i' && strncmp(n, "Blue", 4));
  104.     /* don't show icky things, except Blue icky things.. -CFT */
  105.  
  106.         else if (c=='w' && strncmp(n, "Were", 4) && strncmp(n, "Gian", 4)) {
  107.         if (randint(5)==1) flag = TRUE;
  108.     /* occas. show worms, except Purple worms and Wereworms -CFT */
  109.  
  110.         } else if (c==',' && strncmp(n, "Magic", 5));
  111.     /* don't show mushrooms, except magic 'shrooms -CFT */
  112.  
  113.         else if (!(c_list[m_ptr->mptr].cdefense & MINDLESS))
  114.         flag = TRUE;
  115.     /* if not mindless, they show up -CWS */
  116.     }
  117.  
  118.     /* Normal sight.         */
  119.     if (los(char_row, char_col, (int)m_ptr->fy, (int)m_ptr->fx)) {
  120.         c_ptr = &cave[m_ptr->fy][m_ptr->fx];
  121.  
  122. #ifdef GROSS_HACK
  123.     /* Try to debug invis monsters...this is not 'fixed', per se
  124.      * but it will correct the observed problem and also give me
  125.      * a chance to trap the thing with a debugger.   -CWS
  126.          *******
  127.          * This should no longer be necessary, but it's harmless  -CWS
  128.          */
  129.         if (c_ptr->cptr != monptr) {
  130.         char                BUF[100];
  131.  
  132.         sprintf(BUF, "Help! cptr = %d / monptr = %d, x = %d, y = %d",
  133.             c_ptr->cptr, monptr, m_ptr->fx, m_ptr->fy);
  134.         if (wizard)
  135.             msg_print(BUF);
  136.         c_ptr->cptr = monptr;
  137.         }
  138. #endif  /* GROSS_HACK */
  139.         r_ptr = &c_list[m_ptr->mptr];
  140.     /* moved here to allow infra to see invis -CFT */
  141.         if ((py.flags.see_infra > 0) &&
  142.         (m_ptr->cdis <= py.flags.see_infra)) {
  143.         if (NO_INFRA & r_ptr->cdefense)    /* changed to act sensibly -CFT */
  144.             c_recall[m_ptr->mptr].r_cdefense |= NO_INFRA;
  145.         else
  146.             flag = TRUE;   /* only can see if not NO_INFRA... */
  147.         }
  148.         if (c_ptr->pl || c_ptr->tl ||
  149.         (find_flag && m_ptr->cdis <= light_rad && player_light)) {
  150.  
  151. #ifdef ATARIST_MWC
  152.         holder = CM_INVISIBLE;
  153.         if ((holder & r_ptr->cmove) == 0)
  154. #else
  155.         if ((CM_INVISIBLE & r_ptr->cmove) == 0)
  156. #endif
  157.             flag = TRUE;
  158.         else if (py.flags.see_inv) {
  159.             flag = TRUE;
  160. #ifdef ATARIST_MWC
  161.             c_recall[m_ptr->mptr].r_cmove |= holder;
  162. #else
  163.             c_recall[m_ptr->mptr].r_cmove |= CM_INVISIBLE;
  164. #endif
  165.         }
  166.         }
  167.     }
  168.     }
  169. /* Light it up.     */
  170.     if (flag) {
  171. #ifdef TC_COLOR
  172.     if (!no_color_flag)       /* don't waste time if no color -CFT */
  173.         lite_spot((int)m_ptr->fy, (int)m_ptr->fx);
  174. /* redraw, even if lit, so MHD's change color -CFT */
  175. #endif
  176.     if (!m_ptr->ml) {
  177.         disturb(1, 0);
  178.         m_ptr->ml = TRUE;
  179.         lite_spot((int)m_ptr->fy, (int)m_ptr->fx);
  180.         screen_change = TRUE;  /* notify inven_command */
  181.     }
  182.     }
  183. /* Turn it off.     */
  184.     else if (m_ptr->ml) {
  185.     m_ptr->ml = FALSE;
  186.     lite_spot((int)m_ptr->fy, (int)m_ptr->fx);
  187.     screen_change = TRUE;       /* notify inven_command */
  188.     }
  189. }
  190.  
  191.  
  192. /* Given speed,  returns number of moves this turn.     -RAK-   */
  193. /* NOTE: Player must always move at least once per iteration,
  194.  *       a slowed player is handled by moving monsters faster
  195.  *
  196.  * monnum = index in m_list[] now passed in, so (turn+monnum) can
  197.  *          be used to vary when monsters move. -CFT
  198.  */
  199.  
  200. int
  201. movement_rate(monnum)
  202. int monnum;
  203. {
  204.   register int ps, ms, tm, i;
  205.  
  206.   ps = 1 - py.flags.speed;    /* this makes normal = 1, fast = 2,
  207.                                  * v.fast = 3, slow = 0, v.slow = -1 -CFT */
  208.   ms = m_list[monnum].cspeed;
  209.   
  210.   i = (int)(turn & 0xFF) + (int)monnum; /* 0xFF to prevent negative values -CFT */
  211.  
  212.   if (ps == ms)
  213.       return 1;            /* same spd as player -CFT */
  214.  
  215.   if (ps<1 && ms<1) {        /* both slow, swap "reciprocals" -CFT */
  216.       tm = 2 - ps;
  217.       ps = 2 - ms;
  218.       ms = tm;
  219.   }
  220.  
  221.   if (ps < 1)            /* then mon must be fast, or above would */
  222.       return ms * (2 - ps);    /* have happened -CFT */
  223.  
  224.   if (ms<1)            /* then player fast... move once in a while -CFT */
  225.     return !(i % (ps * (2 - ms)));
  226.  
  227. /* player faster.         
  228.  * This formula is not intuitive, but it effectively uses the turn counter
  229.  * (offset by the monster index, so not every monster moves at same time)
  230.  * to compute factional parts of movement ratios.. so that a monster 2/3 the
  231.  * player's spd will move twice every 3 turns.  An earlier version of this
  232.  * equation performed the same result on average, but it was prone to "clumps"
  233.  * of speed... if the player was spd 4, and the monster spd 2, then for each
  234.  * 4 turn cycle, the monster would move 0,0,1,1.  This equation will result
  235.  * in 0,1,0,1, which is better. -CFT
  236.  */
  237.  
  238.   if (ps>ms)
  239.     return (((i*ms) % ps) < ms);
  240.  
  241.   if (!(tm = (ms % ps)))    /* divides evenly, simple case -CFT */
  242.     return (ms / ps);
  243.  
  244.   /* Like the player-faster formula, this is NOT intuitive.  However, it
  245.    * effectively uses the turn counter & monster index to decide when a
  246.    *  monster should get an "extra" move.  It also prevents "clumps". -CFT
  247.    */
  248.   return ((ms / ps) + (((i*tm) % ps) < tm));
  249. }
  250.  
  251. /* Makes sure a new creature gets lit up.            -CJS- */
  252. static int 
  253. check_mon_lite(y, x)
  254.     int y, x;
  255. {
  256.     register int monptr;
  257.  
  258.     monptr = cave[y][x].cptr;
  259.     if (monptr <= 1)
  260.     return FALSE;
  261.     else {
  262.     update_mon(monptr);
  263.     return m_list[monptr].ml;
  264.     }
  265. }
  266.  
  267.  
  268. /* Choose correct directions for monster movement    -RAK-     */
  269. static void 
  270. get_moves(monptr, mm)
  271.     int          monptr;
  272.     register int *mm;
  273. {
  274.     int y, ay, x, ax, move_val;
  275.  
  276.     y = m_list[monptr].fy - char_row;
  277.     x = m_list[monptr].fx - char_col;
  278.  
  279. /* lvl  1..15 always afraid, 16..22 some, based on maxhp %8 :
  280.  * lvl  16    7 of 8 monsters afraid  [  this is for a 50th  ]
  281.  * lvl  22    1 of 8 monsters afraid  [  level player, lower ]
  282.  * lvl  23++  no afraid monsters      [ level=less afraid m. ]
  283.  */
  284.  
  285.     if (((int16)(py.misc.lev - 34 - c_list[(m_list[monptr]).mptr].level +
  286.          ((m_list[monptr].maxhp) % 8)) > 0)
  287.     || m_list[monptr].monfear) { /* Run away!  Run away! -DGK */
  288.     y = (-y);     /* FIXME: make monsters running away more intelligent */
  289.     x = (-x);
  290.     }
  291.  
  292.     if (y < 0) {
  293.     move_val = 8;
  294.     ay = (-y);
  295.     } else {
  296.     move_val = 0;
  297.     ay = y;
  298.     }
  299.     if (x > 0) {
  300.     move_val += 4;
  301.     ax = x;
  302.     } else
  303.     ax = (-x);
  304.  
  305. /* this has the advantage of preventing the diamond maneuvre, also faster */
  306.     if (ay > (ax << 1))
  307.     move_val += 2;
  308.     else if (ax > (ay << 1))
  309.     move_val++;
  310.     switch (move_val) {
  311.       case 0:
  312.     mm[0] = 9;
  313.     if (ay > ax) {
  314.         mm[1] = 8;
  315.         mm[2] = 6;
  316.         mm[3] = 7;
  317.         mm[4] = 3;
  318.     } else {
  319.         mm[1] = 6;
  320.         mm[2] = 8;
  321.         mm[3] = 3;
  322.         mm[4] = 7;
  323.     }
  324.     break;
  325.       case 1:
  326.       case 9:
  327.     mm[0] = 6;
  328.     if (y < 0) {
  329.         mm[1] = 3;
  330.         mm[2] = 9;
  331.         mm[3] = 2;
  332.         mm[4] = 8;
  333.     } else {
  334.         mm[1] = 9;
  335.         mm[2] = 3;
  336.         mm[3] = 8;
  337.         mm[4] = 2;
  338.     }
  339.     break;
  340.       case 2:
  341.       case 6:
  342.     mm[0] = 8;
  343.     if (x < 0) {
  344.         mm[1] = 9;
  345.         mm[2] = 7;
  346.         mm[3] = 6;
  347.         mm[4] = 4;
  348.     } else {
  349.         mm[1] = 7;
  350.         mm[2] = 9;
  351.         mm[3] = 4;
  352.         mm[4] = 6;
  353.     }
  354.     break;
  355.       case 4:
  356.     mm[0] = 7;
  357.     if (ay > ax) {
  358.         mm[1] = 8;
  359.         mm[2] = 4;
  360.         mm[3] = 9;
  361.         mm[4] = 1;
  362.     } else {
  363.         mm[1] = 4;
  364.         mm[2] = 8;
  365.         mm[3] = 1;
  366.         mm[4] = 9;
  367.     }
  368.     break;
  369.       case 5:
  370.       case 13:
  371.     mm[0] = 4;
  372.     if (y < 0) {
  373.         mm[1] = 1;
  374.         mm[2] = 7;
  375.         mm[3] = 2;
  376.         mm[4] = 8;
  377.     } else {
  378.         mm[1] = 7;
  379.         mm[2] = 1;
  380.         mm[3] = 8;
  381.         mm[4] = 2;
  382.     }
  383.     break;
  384.       case 8:
  385.     mm[0] = 3;
  386.     if (ay > ax) {
  387.         mm[1] = 2;
  388.         mm[2] = 6;
  389.         mm[3] = 1;
  390.         mm[4] = 9;
  391.     } else {
  392.         mm[1] = 6;
  393.         mm[2] = 2;
  394.         mm[3] = 9;
  395.         mm[4] = 1;
  396.     }
  397.     break;
  398.       case 10:
  399.       case 14:
  400.     mm[0] = 2;
  401.     if (x < 0) {
  402.         mm[1] = 3;
  403.         mm[2] = 1;
  404.         mm[3] = 6;
  405.         mm[4] = 4;
  406.     } else {
  407.         mm[1] = 1;
  408.         mm[2] = 3;
  409.         mm[3] = 4;
  410.         mm[4] = 6;
  411.     }
  412.     break;
  413.       case 12:
  414.     mm[0] = 1;
  415.     if (ay > ax) {
  416.         mm[1] = 2;
  417.         mm[2] = 4;
  418.         mm[3] = 3;
  419.         mm[4] = 7;
  420.     } else {
  421.         mm[1] = 4;
  422.         mm[2] = 2;
  423.         mm[3] = 7;
  424.         mm[4] = 3;
  425.     }
  426.     break;
  427.     }
  428. }
  429.  
  430. static int 
  431. monster_critical(dice, sides, dam)
  432. int dice, sides, dam;
  433. {
  434.     int total = dice * sides;
  435.     int max = 0;
  436.  
  437.     if (dam == total && dam > 20)
  438.     max = 1;
  439.     if ((dam > (19 * total) / 20) && ((dam < 20) ? randint(20) == 1 : TRUE)) {
  440.     if (dam > 20)
  441.         while (randint(50) == 1)
  442.         max++;
  443.     if (dam > 45)
  444.         return 6 + max;
  445.     if (dam > 33)
  446.         return 5 + max;
  447.     if (dam > 25)
  448.         return 4 + max;
  449.     if (dam > 18)
  450.         return 3 + max;
  451.     if (dam > 11)
  452.         return 2 + max;
  453.     return 1 + max;
  454.     }
  455.     return 0;
  456. }
  457.  
  458. /* Make an attack on the player (chuckle.)        -RAK-     */
  459. static void 
  460. make_attack(monptr)
  461. int monptr;
  462. {
  463.     int                    attype, adesc, adice, asides;
  464.     int                    i, j, damage, flag, attackn, notice, visible;
  465.     int                    shatter = FALSE;
  466.     int                    CUT = FALSE, STUN = FALSE;
  467.     int32                  gold;
  468.     attid                  *attstr, *attstr_orig;
  469.     vtype                  cdesc, tmp_str, ddesc;
  470.     register creature_type *r_ptr;
  471.     monster_type           *m_ptr;
  472.     register struct misc   *p_ptr;
  473.     register struct flags  *f_ptr;
  474.     register inven_type    *i_ptr;
  475.     int8u                  blinked = 0;    /* flag to see if blinked away (after
  476.                      * steal) -CFT */
  477.  
  478.     if (death)                    /* don't beat a dead body! */
  479.     return;
  480.  
  481.     m_ptr = &m_list[monptr];
  482.     r_ptr = &c_list[m_ptr->mptr];
  483.  
  484.     if (r_ptr->cdefense & DESTRUCT)
  485.     shatter = TRUE;
  486.  
  487.     if (!m_ptr->ml)
  488.     (void)strcpy(cdesc, "It ");
  489.     else {
  490.     if (c_list[m_ptr->mptr].cdefense & UNIQUE)
  491.         (void)sprintf(cdesc, "%s ", r_ptr->name);
  492.     else
  493.         (void)sprintf(cdesc, "The %s ", r_ptr->name);
  494.     }
  495.  
  496. /* For "DIED_FROM" string       */
  497.     if (r_ptr->cdefense & UNIQUE)
  498.     (void)sprintf(ddesc, "%s", r_ptr->name);
  499.     else if (is_a_vowel(r_ptr->name[0]))
  500.     (void)sprintf(ddesc, "an %s", r_ptr->name);
  501.     else
  502.     (void)sprintf(ddesc, "a %s", r_ptr->name);
  503. /* End DIED_FROM           */
  504.  
  505.     attackn = 0;
  506.     attstr = r_ptr->damage;
  507.     attstr_orig = attstr;
  508.  
  509.  /* if has no attacks (*attstr starts off 0), still loop once to accumulate
  510.   * notices that it has no attacks - dbd
  511.   */
  512.     while ((*attstr != 0 || attstr == attstr_orig) && !death && !blinked) {
  513.     attype = monster_attacks[*attstr].attack_type;
  514.     adesc = monster_attacks[*attstr].attack_desc;
  515.     adice = monster_attacks[*attstr].attack_dice;
  516.     asides = monster_attacks[*attstr].attack_sides;
  517.     attstr++;
  518.     flag = FALSE;
  519.     if (((py.flags.protevil > 0) && (r_ptr->cdefense & EVIL) &&
  520.          ((py.misc.lev + 1) > r_ptr->level)) &&
  521.         (randint(100) + (py.misc.lev) > 50))
  522.     /* Random (100) + level > 50 chance for stop any attack added */
  523.     {
  524.         if (m_ptr->ml)
  525.         c_recall[m_ptr->mptr].r_cdefense |= EVIL;
  526.         attype = 99;
  527.         adesc = 99;
  528.     }
  529.     p_ptr = &py.misc;
  530.     switch (attype) {
  531.       case 1:           /* Normal attack  */
  532.         if (test_hit(60, (int)r_ptr->level, 0, p_ptr->pac + p_ptr->ptoac,
  533.              CLA_MISC_HIT))
  534.         flag = TRUE;
  535.         break;
  536.       case 2:           /* Lose Strength */
  537.         if (test_hit(-3, (int)r_ptr->level, 0, p_ptr->pac + p_ptr->ptoac,
  538.              CLA_MISC_HIT))
  539.         flag = TRUE;
  540.         break;
  541.       case 3:           /* Confusion attack */
  542.         if (test_hit(10, (int)r_ptr->level, 0, p_ptr->pac + p_ptr->ptoac,
  543.              CLA_MISC_HIT))
  544.         flag = TRUE;
  545.         break;
  546.       case 4:           /* Fear attack    */
  547.         if (test_hit(10, (int)r_ptr->level, 0, p_ptr->pac + p_ptr->ptoac,
  548.              CLA_MISC_HIT))
  549.         flag = TRUE;
  550.         break;
  551.       case 5:           /* Fire attack    */
  552.         if (test_hit(10, (int)r_ptr->level, 0, p_ptr->pac + p_ptr->ptoac,
  553.              CLA_MISC_HIT))
  554.         flag = TRUE;
  555.         break;
  556.       case 6:           /* Acid attack    */
  557.         if (test_hit(0, (int)r_ptr->level, 0, p_ptr->pac + p_ptr->ptoac,
  558.              CLA_MISC_HIT))
  559.         flag = TRUE;
  560.         break;
  561.       case 7:           /* Cold attack    */
  562.         if (test_hit(10, (int)r_ptr->level, 0, p_ptr->pac + p_ptr->ptoac,
  563.              CLA_MISC_HIT))
  564.         flag = TRUE;
  565.         break;
  566.       case 8:           /* Lightning attack */
  567.         if (test_hit(10, (int)r_ptr->level, 0, p_ptr->pac + p_ptr->ptoac,
  568.              CLA_MISC_HIT))
  569.         flag = TRUE;
  570.         break;
  571.       case 9:           /* Corrosion attack */
  572.         if (test_hit(0, (int)r_ptr->level, 0, p_ptr->pac + p_ptr->ptoac,
  573.              CLA_MISC_HIT))
  574.         flag = TRUE;
  575.         break;
  576.       case 10:           /* Blindness attack */
  577.         if (test_hit(2, (int)r_ptr->level, 0, p_ptr->pac + p_ptr->ptoac,
  578.              CLA_MISC_HIT))
  579.         flag = TRUE;
  580.         break;
  581.       case 11:           /* Paralysis attack */
  582.         if (test_hit(2, (int)r_ptr->level, 0, p_ptr->pac + p_ptr->ptoac,
  583.              CLA_MISC_HIT))
  584.         flag = TRUE;
  585.         break;
  586.       case 12:           /* Steal Money    */
  587.         if ((test_hit(5, (int)r_ptr->level, 0, (int)py.misc.lev,
  588.               CLA_MISC_HIT))
  589.         && (py.misc.au > 0))
  590.         flag = TRUE;
  591.         break;
  592.       case 13:           /* Steal Object   */
  593.         if ((test_hit(2, (int)r_ptr->level, 0, (int)py.misc.lev,
  594.               CLA_MISC_HIT))
  595.         && (inven_ctr > 0))
  596.         flag = TRUE;
  597.         break;
  598.       case 14:           /* Poison           */
  599.         if (test_hit(5, (int)r_ptr->level, 0, p_ptr->pac + p_ptr->ptoac,
  600.              CLA_MISC_HIT))
  601.         flag = TRUE;
  602.         break;
  603.       case 15:           /* Lose dexterity */
  604.         if (test_hit(0, (int)r_ptr->level, 0, p_ptr->pac + p_ptr->ptoac,
  605.              CLA_MISC_HIT))
  606.         flag = TRUE;
  607.         break;
  608.       case 16:           /* Lose constitution */
  609.         if (test_hit(0, (int)r_ptr->level, 0, p_ptr->pac + p_ptr->ptoac,
  610.              CLA_MISC_HIT))
  611.         flag = TRUE;
  612.         break;
  613.       case 17:           /* Lose intelligence */
  614.         if (test_hit(2, (int)r_ptr->level, 0, p_ptr->pac + p_ptr->ptoac,
  615.              CLA_MISC_HIT))
  616.         flag = TRUE;
  617.         break;
  618.       case 18:           /* Lose wisdom */
  619.         if (test_hit(2, (int)r_ptr->level, 0, p_ptr->pac + p_ptr->ptoac,
  620.              CLA_MISC_HIT))
  621.         flag = TRUE;
  622.         break;
  623.       case 19:           /* Lose experience */
  624.         if (test_hit(5, (int)r_ptr->level, 0, p_ptr->pac + p_ptr->ptoac,
  625.              CLA_MISC_HIT))
  626.         flag = TRUE;
  627.         break;
  628.       case 20:           /* Aggravate monsters */
  629.         flag = TRUE;
  630.         break;
  631.       case 21:           /* Disenchant      */
  632.         if (test_hit(20, (int)r_ptr->level, 0, p_ptr->pac + p_ptr->ptoac,
  633.              CLA_MISC_HIT))
  634.         flag = TRUE;
  635.         break;
  636.       case 22:           /* Eat food      */
  637.         if (test_hit(5, (int)r_ptr->level, 0, p_ptr->pac + p_ptr->ptoac,
  638.              CLA_MISC_HIT))
  639.         flag = TRUE;
  640.         break;
  641.       case 23:           /* Eat light      */
  642.         if (test_hit(5, (int)r_ptr->level, 0, p_ptr->pac + p_ptr->ptoac,
  643.              CLA_MISC_HIT))
  644.         flag = TRUE;
  645.         break;
  646.       case 24:           /* Eat charges      */
  647.         if ((test_hit(15, (int)r_ptr->level, 0, p_ptr->pac + p_ptr->ptoac,
  648.               CLA_MISC_HIT)) &&
  649.         (inven_ctr > 0))   /* check to make sure an object exists */
  650.         flag = TRUE;
  651.         break;
  652.       case 25:           /* Drain all stats   */
  653.         if ((test_hit(2, (int)r_ptr->level, 0, p_ptr->pac + p_ptr->ptoac,
  654.               CLA_MISC_HIT)))
  655.         flag = TRUE;
  656.         break;
  657.       case 99:
  658.         flag = TRUE;
  659.         break;
  660.       case 0:           /* Monster has no physical attacks - dbd */
  661.         flag = TRUE;
  662.         break;
  663.       default:
  664.         break;
  665.     }
  666. /* can not strcat to cdesc because the creature may have multiple attacks */
  667.     if (flag) {
  668.         disturb(1, 0);
  669.         (void)strcpy(tmp_str, cdesc);
  670.         CUT = STUN = FALSE;
  671.         switch (adesc) {
  672.           case 1:
  673.         msg_print(strcat(tmp_str, "hits you."));
  674.         CUT = TRUE;
  675.         STUN = TRUE;
  676.         break;
  677.           case 2:
  678.         msg_print(strcat(tmp_str, "bites you."));
  679.         CUT = TRUE;
  680.         break;
  681.           case 3:
  682.         msg_print(strcat(tmp_str, "claws you."));
  683.         CUT = TRUE;
  684.         break;
  685.           case 4:
  686.         msg_print(strcat(tmp_str, "stings you."));
  687.         break;
  688.           case 5:
  689.         msg_print(strcat(tmp_str, "touches you."));
  690.         break;
  691.           case 6:
  692.         msg_print(strcat(tmp_str, "kicks you."));
  693.         break;
  694.           case 7:
  695.         msg_print(strcat(tmp_str, "gazes at you."));
  696.         break;
  697.           case 8:
  698.         msg_print(strcat(tmp_str, "breathes on you."));
  699.         break;
  700.           case 9:
  701.         msg_print(strcat(tmp_str, "spits on you."));
  702.         break;
  703.           case 10:
  704.         msg_print(strcat(tmp_str, "makes a horrible wail."));
  705.         break;
  706.           case 11:
  707.         msg_print(strcat(tmp_str, "embraces you."));
  708.         break;
  709.           case 12:
  710.         msg_print(strcat(tmp_str, "crawls on you."));
  711.         break;
  712.           case 13:
  713.         msg_print(strcat(tmp_str, "releases a cloud of spores."));
  714.         break;
  715.           case 14:
  716.         msg_print(strcat(tmp_str, "begs you for money."));
  717.         break;
  718.           case 15:
  719.         msg_print("You've been slimed!");
  720.         break;
  721.           case 16:
  722.         msg_print(strcat(tmp_str, "crushes you."));
  723.         break;
  724.           case 17:
  725.         msg_print(strcat(tmp_str, "tramples you."));
  726.         STUN = TRUE;
  727.         break;
  728.           case 18:
  729.         msg_print(strcat(tmp_str, "drools on you."));
  730.         break;
  731.           case 19:
  732.         switch (randint(9)) {
  733.           case 1:
  734.             msg_print(strcat(tmp_str, "insults you!"));
  735.             break;
  736.           case 2:
  737.             msg_print(strcat(tmp_str, "insults your mother!"));
  738.             break;
  739.           case 3:
  740.             msg_print(strcat(tmp_str, "gives you the finger!"));
  741.             break;
  742.           case 4:
  743.             msg_print(strcat(tmp_str, "humiliates you!"));
  744.             break;
  745.           case 5:
  746.             msg_print(strcat(tmp_str, "wets on your leg!"));
  747.             break;
  748.           case 6:
  749.             msg_print(strcat(tmp_str, "defiles you!"));
  750.             break;
  751.           case 7:
  752.             msg_print(strcat(tmp_str, "dances around you!"));
  753.             break;
  754.           case 8:
  755.             msg_print(strcat(tmp_str, "makes obscene gestures!"));
  756.             break;
  757.           case 9:
  758.             msg_print(strcat(tmp_str, "moons you!!!"));
  759.             break;
  760.         }
  761.         break;
  762.           case 20:
  763.         msg_print(strcat(tmp_str, "butts you."));
  764.         STUN = TRUE;
  765.         break;
  766.           case 21:
  767.         msg_print(strcat(tmp_str, "charges you."));
  768.         STUN = TRUE;
  769.         break;
  770.           case 22:
  771.         msg_print(strcat(tmp_str, "engulfs you."));
  772.         break;
  773.           case 23:
  774.         switch (randint(5)) {
  775.           case 1:
  776.             msg_print(strcat(tmp_str, "wants his mushrooms back. "));
  777.             break;
  778.           case 2:
  779.             msg_print(strcat(tmp_str, "tells you to get off his land. "));
  780.             break;
  781.           case 3:
  782.             msg_print(strcat(tmp_str, "looks for his dogs. "));
  783.             break;
  784.           case 4:
  785.             msg_print(strcat(tmp_str, "says 'Did you kill my Fang?' "));
  786.             break;
  787.           case 5:
  788.             msg_print(strcat(tmp_str,
  789.                   "asks 'Do you want to buy any mushrooms?' "));
  790.             break;
  791.         }
  792.         break;
  793.           case 99:
  794.         msg_print(strcat(tmp_str, "is repelled."));
  795.         break;
  796.           default:        /* no message for case 0 because no attacks - dbd */
  797.         break;
  798.         }
  799.  
  800.         notice = TRUE;
  801.     /*
  802.      * always fail to notice attack if creature invisible, set notice and
  803.      * visible here since creature may be visible when attacking and then
  804.      * teleport afterwards (becoming effectively invisible) 
  805.      */
  806.         if (!m_ptr->ml) {
  807.         visible = FALSE;
  808.         notice = FALSE;
  809.         } else
  810.         visible = TRUE;
  811.  
  812.         damage = damroll(adice, asides);
  813.         switch (attype) {
  814.           case 0: /* No physical attacks */
  815.  
  816. /* put something here to notice if monster *has* no physical attacks -CWS */
  817.         if (!randint(10))
  818.             notice = TRUE;
  819.         break;
  820.  
  821.           case 1:           /* Normal attack     */
  822.         /* round half-way case down */
  823.         damage -= ((((((p_ptr->pac + p_ptr->ptoac) > 150) ? 150 :
  824.              (p_ptr->pac + p_ptr->ptoac)) * 3) / 4) * damage) / 200;
  825.         take_hit(damage, ddesc);
  826.         if ((damage > 23) && shatter)
  827.             shatter_quake(m_ptr->fy, m_ptr->fx);
  828.         break;
  829.           case 2:           /* Lose Strength */
  830.         take_hit(damage, ddesc);
  831.         if (py.flags.sustain_str)
  832.             msg_print("You feel weaker for a moment, but it passes.");
  833.         else if (randint(2) == 1) {
  834.             msg_print("You feel weaker.");
  835.             (void)dec_stat(A_STR);
  836.         } else
  837.             notice = FALSE;
  838.         break;
  839.           case 3:           /* Confusion attack */
  840.         f_ptr = &py.flags;
  841.         take_hit(damage, ddesc);
  842.         if ((!py.flags.confusion_resist) && (!py.flags.chaos_resist)) {
  843.             if (randint(2) == 1) {
  844.             if (f_ptr->confused < 1) {
  845.                 msg_print("You feel confused.");
  846.                 f_ptr->confused += randint((int)r_ptr->level);
  847.             } else
  848.                 notice = FALSE;
  849.             f_ptr->confused += 3;
  850.             } else
  851.             notice = FALSE;
  852.         }
  853.         break;
  854.           case 4:           /* Fear attack     */
  855.         f_ptr = &py.flags;
  856.         take_hit(damage, ddesc);
  857.         if (player_saves() || (py.misc.pclass == 1 && randint(3) == 1)
  858.             || py.flags.fear_resist)
  859.             msg_print("You stand your ground!");
  860.         else if (f_ptr->afraid < 1) {
  861.             msg_print("You are suddenly afraid!");
  862.             f_ptr->afraid += 3 + randint((int)r_ptr->level);
  863.         } else {
  864.             f_ptr->afraid += 3;
  865.             notice = FALSE;
  866.         }
  867.         break;
  868.           case 5:           /* Fire attack     */
  869.         msg_print("You are enveloped in flames!");
  870.         fire_dam(damage, ddesc);
  871.         break;
  872.           case 6:           /* Acid attack     */
  873.         msg_print("You are covered in acid!");
  874.         acid_dam(damage, ddesc);
  875.         break;
  876.           case 7:           /* Cold attack     */
  877.         msg_print("You are covered with frost!");
  878.         cold_dam(damage, ddesc);
  879.         break;
  880.           case 8:           /* Lightning attack */
  881.         msg_print("Lightning strikes you!");
  882.         light_dam(damage, ddesc);
  883.         break;
  884.           case 9:           /* Corrosion attack */
  885.         msg_print("A stinging red gas swirls about you.");
  886.         corrode_gas(ddesc);
  887.         take_hit(damage, ddesc);
  888.         break;
  889.           case 10:           /* Blindness attack */
  890.         f_ptr = &py.flags;
  891.         take_hit(damage, ddesc);
  892.         if (!py.flags.blindness_resist) {
  893.             if (f_ptr->blind < 1) {
  894.             f_ptr->blind += 10 + randint((int)r_ptr->level);
  895.             msg_print("Your eyes begin to sting.");
  896.             } else {
  897.             f_ptr->blind += 5;
  898.             notice = FALSE;
  899.             }
  900.         }
  901.         break;
  902.           case 11:           /* Paralysis attack */
  903.         f_ptr = &py.flags;
  904.         take_hit(damage, ddesc);
  905.         if (player_saves())
  906.             msg_print("You resist the effects!");
  907.         else if (f_ptr->paralysis < 1) {
  908.             if (f_ptr->free_act)
  909.             msg_print("You are unaffected.");
  910.             else {
  911.             f_ptr->paralysis = randint((int)r_ptr->level) + 3;
  912.             msg_print("You are paralysed.");
  913.             }
  914.         } else
  915.             notice = FALSE;
  916.         break;
  917.           case 12:           /* Steal Money      */
  918.         if ((py.flags.paralysis < 1) &&
  919.             (randint(168) < py.stats.use_stat[A_DEX]))
  920.         /* immune to steal at 18/150 */
  921.             msg_print("You quickly protect your money pouch!");
  922.         else {           /* make this more sane.... -CWS */
  923.             vtype               t1;
  924.  
  925.             gold = (p_ptr->au / 10) + randint(25);
  926.             if (gold > 5000)
  927.             gold = 2000 + randint(1000) + (p_ptr->au / 20);
  928.             if (gold > p_ptr->au)
  929.             gold = p_ptr->au;
  930.             p_ptr->au -= gold;
  931.             msg_print("Your purse feels lighter.");
  932.             sprintf(t1, "%ld coin%s stolen!", (long)gold,
  933.                 (gold > 1L) ? "s were" : " was");
  934.             msg_print(t1);
  935.             prt_gold();
  936.         }
  937.         if (randint(2) == 1) {
  938.             msg_print("There is a puff of smoke!");
  939.             blinked = 1;   /* added -CFT */
  940.             teleport_away(monptr, MAX_SIGHT);
  941.         }
  942.         break;
  943.           case 13:           /* Steal Object     */
  944.         if ((py.flags.paralysis < 1) &&
  945.             (randint(168) < py.stats.use_stat[A_DEX]))
  946.         /* immune to steal at 18/150 change */
  947.             msg_print("You grab hold of your backpack!");
  948.         else {
  949.             vtype               t1, t2;
  950.  
  951.             i = randint(inven_ctr) - 1;
  952.             if ((inventory[i].tval >= TV_MIN_WEAR) &&
  953.             (inventory[i].tval <= TV_MAX_WEAR) &&
  954.             (inventory[i].flags2 & TR_ARTIFACT))
  955.             break;       /* don't destroy artifacts -CFT */
  956.             objdes(t1, &inventory[i], FALSE);
  957. /* stacked single items */
  958.             sprintf(t2, "%sour %s (%c) %s stolen!",
  959.               ((inventory[i].subval <= ITEM_SINGLE_STACK_MAX) &&
  960.                (inventory[i].number > 1))
  961.                 ? "One of y" : "Y",
  962.                 t1, i + 'a',
  963. /* stacked group items */
  964.                 ((inventory[i].subval > ITEM_SINGLE_STACK_MAX) &&
  965.                  (inventory[i].number > 1))
  966.                 ? "were" : "was");
  967.             msg_print(t2);
  968.             inven_destroy(i);
  969.         }
  970.         if (randint(3) == 1) {
  971.             msg_print("There is a puff of smoke!");
  972.             blinked = 1;   /* added -CFT */
  973.             teleport_away(monptr, MAX_SIGHT);
  974.         }
  975.         break;
  976.           case 14:           /* Poison     */
  977.         f_ptr = &py.flags;
  978.         take_hit(damage, ddesc);
  979.         if (!(f_ptr->poison_im || f_ptr->poison_resist ||
  980.               f_ptr->resist_poison)) {
  981.             msg_print("You feel very sick.");
  982.             f_ptr->poisoned += randint((int)r_ptr->level) + 5;
  983.         } else {
  984.             msg_print("The poison has no effect.");
  985.         }
  986.         break;
  987.           case 15:           /* Lose dexterity */
  988.         f_ptr = &py.flags;
  989.         take_hit(damage, ddesc);
  990.         if (f_ptr->sustain_dex)
  991.             msg_print("You feel clumsy for a moment, but it passes.");
  992.         else {
  993.             msg_print("You feel more clumsy.");
  994.             (void)dec_stat(A_DEX);
  995.         }
  996.         break;
  997.           case 16:           /* Lose constitution */
  998.         f_ptr = &py.flags;
  999.         take_hit(damage, ddesc);
  1000.         if (f_ptr->sustain_con)
  1001.             msg_print("Your body resists the effects of the disease.");
  1002.         else {
  1003.             msg_print("Your health is damaged!");
  1004.             (void)dec_stat(A_CON);
  1005.         }
  1006.         break;
  1007.           case 17:           /* Lose intelligence */
  1008.         f_ptr = &py.flags;
  1009.         take_hit(damage, ddesc);
  1010.         msg_print("You have trouble thinking clearly.");
  1011.         if (f_ptr->sustain_int)
  1012.             msg_print("But your mind quickly clears.");
  1013.         else
  1014.             (void)dec_stat(A_INT);
  1015.         break;
  1016.           case 18:           /* Lose wisdom       */
  1017.         f_ptr = &py.flags;
  1018.         take_hit(damage, ddesc);
  1019.         if (f_ptr->sustain_wis)
  1020.             msg_print("Your wisdom is sustained.");
  1021.         else {
  1022.             msg_print("Your wisdom is drained.");
  1023.             (void)dec_stat(A_WIS);
  1024.         }
  1025.         break;
  1026.           case 19:           /* Lose experience  */
  1027.         f_ptr = &py.flags;
  1028.         if (f_ptr->hold_life && randint(5) > 1)
  1029.             msg_print("You keep hold of your life force!");
  1030.         else {
  1031.             if (f_ptr->hold_life) {
  1032.             msg_print("You feel your life slipping away!");
  1033.             lose_exp(damage + (py.misc.exp/1000) * MON_DRAIN_LIFE);
  1034.             } else {
  1035.             msg_print("You feel your life draining away!");
  1036.             lose_exp(damage + (py.misc.exp/100) * MON_DRAIN_LIFE);
  1037.             }
  1038.         }
  1039.         break;
  1040.           case 20:           /* Aggravate monster */
  1041.         (void)aggravate_monster(20);
  1042.         break;
  1043.           case 21:           /* Disenchant       */
  1044.         if (!py.flags.disenchant_resist) {
  1045.             int8u               chance = 0;
  1046.  
  1047.             take_hit(damage, ddesc);
  1048.             flag = FALSE;
  1049.             switch (randint(7)) {
  1050.               case 1:
  1051.             i = INVEN_WIELD;
  1052.             break;
  1053.               case 2:
  1054.             i = INVEN_BODY;
  1055.             break;
  1056.               case 3:
  1057.             i = INVEN_ARM;
  1058.             break;
  1059.               case 4:
  1060.             i = INVEN_OUTER;
  1061.             break;
  1062.               case 5:
  1063.             i = INVEN_HANDS;
  1064.             break;
  1065.               case 6:
  1066.             i = INVEN_HEAD;
  1067.             break;
  1068.               case 7:
  1069.             i = INVEN_FEET;
  1070.             break;
  1071.             }
  1072.             i_ptr = &inventory[i];
  1073.             if (i_ptr->tval != TV_NOTHING) {
  1074.             if (i_ptr->flags2 & TR_ARTIFACT)
  1075.                 chance = randint(5);
  1076.             if ((i_ptr->tohit > 0) && (chance < 3)){
  1077.                 i_ptr->tohit -= randint(2);
  1078.                 /* don't send it below zero */
  1079.                 if (i_ptr->tohit < 0)
  1080.                 i_ptr->tohit = 0;
  1081.                 flag = TRUE;
  1082.             }
  1083.             if ((i_ptr->todam > 0) && (chance < 3)) {
  1084.                 i_ptr->todam -= randint(2);
  1085.                 /* don't send it below zero */
  1086.                 if (i_ptr->todam < 0)
  1087.                 i_ptr->todam = 0;
  1088.                 flag = TRUE;
  1089.             }
  1090.             if ((i_ptr->toac > 0) && (chance < 3)) {
  1091.                 i_ptr->toac  -= randint(2);
  1092.                 /* don't send it below zero */
  1093.                 if (i_ptr->toac < 0)
  1094.                 i_ptr->toac = 0;
  1095.                 flag = TRUE;
  1096.             }
  1097.             if (flag || (chance > 2)) {
  1098.                 vtype t1, t2;
  1099.                 objdes(t1, &inventory[i], FALSE);
  1100.                 if (chance < 3)
  1101.                 sprintf(t2, "Your %s (%c) %s disenchanted!", t1,
  1102.                     i+'a'-INVEN_WIELD,
  1103.                     (inventory[i].number != 1) ? "were":"was");
  1104.                 else
  1105.                 sprintf(t2, "Your %s (%c) %s disenchantment!", t1,
  1106.                     i+'a'-INVEN_WIELD,
  1107.                     (inventory[i].number != 1) ? "resist":"resists");
  1108.                 msg_print (t2);
  1109.                 calc_bonuses ();
  1110.             }
  1111.             else
  1112.                 notice = FALSE;
  1113.             }
  1114.         }
  1115.         break;
  1116.           case 22:           /* Eat food       */
  1117.         if (find_range(TV_FOOD, TV_NEVER, &i, &j)) {
  1118.             inven_destroy(i);
  1119.             msg_print("It got at your rations!");
  1120.         } else
  1121.             notice = FALSE;
  1122.         break;
  1123.           case 23:           /* Eat light       */
  1124.         i_ptr = &inventory[INVEN_LIGHT];
  1125.         if ((i_ptr->p1 > 0) && ((i_ptr->flags2 & TR_ARTIFACT) == 0)) {
  1126.             i_ptr->p1 -= (250 + randint(250));
  1127.             if (i_ptr->p1 < 1)
  1128.             i_ptr->p1 = 1;
  1129.             if (py.flags.blind < 1)
  1130.             msg_print("Your light dims.");
  1131.             else
  1132.             notice = FALSE;
  1133.         } else
  1134.             notice = FALSE;
  1135.         break;
  1136.           case 24:           /* Eat charges      */
  1137.         i = randint(inven_ctr) - 1;
  1138.         j = r_ptr->level;
  1139.         i_ptr = &inventory[i];
  1140.         if (((i_ptr->tval == TV_STAFF) || (i_ptr->tval == TV_WAND))
  1141.             && (i_ptr->p1 > 0)) {
  1142.             m_ptr->hp += j * i_ptr->p1;
  1143.             i_ptr->p1 = 0;
  1144.             if (!known2_p(i_ptr))
  1145.             add_inscribe(i_ptr, ID_EMPTY);
  1146.             msg_print("Energy drains from your pack!");
  1147.         } else
  1148.             notice = FALSE;
  1149.         break;
  1150.           case 25:           /* Drain all stats. Haha! SM */
  1151.         f_ptr = &py.flags;
  1152.         take_hit(damage, ddesc);
  1153.         if (py.flags.sustain_str)
  1154.             msg_print("You feel weaker for a moment, but it passes.");
  1155.         else {
  1156.             msg_print("You feel weaker.");
  1157.             (void)dec_stat(A_STR);
  1158.         }
  1159.         if (f_ptr->sustain_dex)
  1160.             msg_print("You feel clumsy for a moment, but it passes.");
  1161.         else {
  1162.             msg_print("You feel more clumsy.");
  1163.             (void)dec_stat(A_DEX);
  1164.         }
  1165.         if (f_ptr->sustain_con)
  1166.             msg_print("Your body resists the effects of the disease.");
  1167.         else {
  1168.             msg_print("Your health is damaged!");
  1169.             (void)dec_stat(A_CON);
  1170.         }
  1171.         msg_print("You have trouble thinking clearly.");
  1172.         if (f_ptr->sustain_int)
  1173.             msg_print("But your mind quickly clears.");
  1174.         else
  1175.             (void)dec_stat(A_INT);
  1176.         if (f_ptr->sustain_wis)
  1177.             msg_print("Your wisdom is sustained.");
  1178.         else {
  1179.             msg_print("Your wisdom is drained.");
  1180.             (void)dec_stat(A_WIS);
  1181.         }
  1182.         if (f_ptr->sustain_chr)
  1183.             msg_print("You keep your good looks.");
  1184.         else {
  1185.             msg_print("Your features are twisted.");
  1186.             (void)dec_stat(A_CHR);
  1187.         }
  1188.         break;
  1189.           case 99:
  1190.         notice = FALSE;
  1191.         break;
  1192.           default:
  1193.         notice = FALSE;
  1194.         break;
  1195.         }
  1196.  
  1197.         if (CUT && STUN) {
  1198.         switch (randint(2)) {
  1199.           case 1:
  1200.             CUT = FALSE;
  1201.             break;
  1202.           case 2:
  1203.             STUN = FALSE;
  1204.             break;
  1205.         }
  1206.         }
  1207.         switch (monster_critical(adice, asides, damage)) {
  1208.           case 0:
  1209.         break;
  1210.           case 1:
  1211.         if (CUT)
  1212.             cut_player(randint(5));
  1213.         else if (STUN)
  1214.             stun_player(randint(5));
  1215.         break;
  1216.           case 2:
  1217.         if (CUT)
  1218.             cut_player(randint(5) + 5);
  1219.         else if (STUN)
  1220.             stun_player(randint(5) + 5);
  1221.         break;
  1222.           case 3:
  1223.         if (CUT)
  1224.             cut_player(randint(30) + 20);
  1225.         else if (STUN)
  1226.             stun_player(randint(20) + 10);
  1227.         break;
  1228.           case 4:
  1229.         if (CUT)
  1230.             cut_player(randint(70) + 30);
  1231.         else if (STUN)
  1232.             stun_player(randint(40) + 30);
  1233.         break;
  1234.           case 5:
  1235.         if (CUT)
  1236.             cut_player(randint(250) + 50);
  1237.         else if (STUN)
  1238.             stun_player(randint(50) + 40);
  1239.         break;
  1240.           case 6:
  1241.         if (CUT)
  1242.             cut_player(300);
  1243.         else if (STUN)
  1244.             stun_player(randint(60) + 57);
  1245.         break;
  1246.           default:
  1247.         if (CUT)
  1248.             cut_player(5000);
  1249.         else if (STUN)
  1250.             stun_player(100 + randint(10));
  1251.         break;
  1252.         }
  1253.  
  1254. /* moved here from mon_move, so that monster only confused if it actually hits */
  1255.         if (!attype) {    /* if no attacks, monster can't get confused -dbd */
  1256.         if (py.flags.confuse_monster && py.flags.protevil <= 0) {
  1257.             msg_print("Your hands stop glowing.");
  1258.             py.flags.confuse_monster = FALSE;
  1259.             if ((randint(MAX_MONS_LEVEL) < r_ptr->level) ||
  1260.             (CHARM_SLEEP & r_ptr->cdefense))
  1261.             (void)sprintf(tmp_str, "%sis unaffected.", cdesc);
  1262.             else {
  1263.             (void)sprintf(tmp_str, "%sappears confused.", cdesc);
  1264.             m_ptr->confused = TRUE;
  1265.             }
  1266.             msg_print(tmp_str);
  1267.             if (visible && !death && randint(4) == 1)
  1268.             c_recall[m_ptr->mptr].r_cdefense |= r_ptr->cdefense &
  1269.                 CHARM_SLEEP;
  1270.         }
  1271.         }
  1272.  
  1273.     /*
  1274.      * increase number of attacks if notice true, or if had previously
  1275.      * noticed the attack (in which case all this does is help player
  1276.      * learn damage), note that in the second case do not increase
  1277.      * attacks if creature repelled (no damage done) 
  1278.      */
  1279.         if ((notice ||
  1280.          (c_recall[m_ptr->mptr].r_attacks[attackn] != 0 &&
  1281.           attype != 99))
  1282.         && c_recall[m_ptr->mptr].r_attacks[attackn] < MAX_UCHAR)
  1283.         c_recall[m_ptr->mptr].r_attacks[attackn]++;
  1284.         if (visible && death && c_recall[m_ptr->mptr].r_deaths < MAX_SHORT)
  1285.         c_recall[m_ptr->mptr].r_deaths++;
  1286.     } else {
  1287.         if ((adesc >= 1 && adesc <= 3) || (adesc == 6)) {
  1288.         disturb(1, 0);
  1289.         (void)strcpy(tmp_str, cdesc);
  1290.         msg_print(strcat(tmp_str, "misses you."));
  1291.         }
  1292.     }
  1293.     if (attackn < MAX_MON_NATTACK - 1)
  1294.         attackn++;
  1295.     else
  1296.         break;
  1297.     }
  1298. }
  1299.  
  1300.  
  1301. /* Make the move if possible, five choices        -RAK-     */
  1302. static void 
  1303. make_move(monptr, mm, rcmove)
  1304. int     monptr, *mm;
  1305. int32u *rcmove;
  1306. {
  1307.     int                   i, newy, newx, do_turn, do_move, stuck_door;
  1308.     int32u                movebits;
  1309.     register cave_type    *c_ptr;
  1310.     register monster_type *m_ptr;
  1311.     register inven_type   *t_ptr;
  1312.  
  1313. #ifdef ATARIST_MWC
  1314.     int32u              holder;
  1315. #endif
  1316.  
  1317.     i = 0;
  1318.     do_turn = FALSE;
  1319.     do_move = FALSE;
  1320.     m_ptr = &m_list[monptr];
  1321.     movebits = c_list[m_ptr->mptr].cmove;
  1322.     do {
  1323.     /* Get new position         */
  1324.     newy = m_ptr->fy;
  1325.     newx = m_ptr->fx;
  1326.     (void)mmove(mm[i], &newy, &newx);
  1327.     c_ptr = &cave[newy][newx];
  1328.  
  1329.     if ((i == 4) && (m_ptr->monfear) &&  /* cornered (or things in the way!) -CWS */
  1330.         ((c_ptr->fval > MAX_OPEN_SPACE) || (c_ptr->cptr > 1))) {
  1331.         creature_type      *r_ptr = &c_list[m_ptr->mptr];
  1332.         vtype               m_name, out_val;
  1333.         
  1334.         m_ptr->monfear = 0;
  1335.         if (m_ptr->ml && los(char_row, char_col, m_ptr->fy, m_ptr->fx)) {
  1336.         monster_name(m_name, m_ptr, r_ptr);
  1337.         sprintf(out_val, "%s turns to fight!", m_name);
  1338.         msg_print(out_val);
  1339.         }
  1340.         break;        /* don't try to actually do anything -CWS */
  1341.     }
  1342.  
  1343.     if (c_ptr->fval != BOUNDARY_WALL) {
  1344.     /* Floor is open?           */
  1345.         if (c_ptr->fval <= MAX_OPEN_SPACE)
  1346.         do_move = TRUE;
  1347.     /* Creature moves through walls? */
  1348.         else if (movebits & CM_PHASE) {
  1349.         do_move = TRUE;
  1350.         *rcmove |= CM_PHASE;
  1351.         } else if (c_list[m_ptr->mptr].cdefense & BREAK_WALL) {
  1352.         /* Crunch up those Walls Morgoth and Umber Hulks!!!! */
  1353.         t_ptr = &t_list[c_ptr->tptr];
  1354.         do_move = TRUE;
  1355.         c_recall[m_ptr->mptr].r_cdefense |= BREAK_WALL;
  1356.         if ((t_ptr->tval == TV_CLOSED_DOOR) ||
  1357.             (t_ptr->tval == TV_SECRET_DOOR)) {    /* break the door -CFT  */
  1358.             invcopy(t_ptr, OBJ_OPEN_DOOR);
  1359.             t_ptr->p1 = (-1);          /* make it broken, not just open */
  1360.             c_ptr->fval = CORR_FLOOR;            /* change floor setting */
  1361.             lite_spot(newy, newx);            /* show broken door     */
  1362.             msg_print("You hear a door burst open!");
  1363.             disturb(1, 0);
  1364.         } else                  /* otherwise, break those walls! -CFT */
  1365.             (void)twall(newy, newx, 1, 0);
  1366.         }
  1367.     /* Creature can open doors?       */
  1368.         else if (c_ptr->tptr != 0) {
  1369.         t_ptr = &t_list[c_ptr->tptr];
  1370.         if (movebits & CM_OPEN_DOOR) {    /* Creature can open doors. */
  1371.             stuck_door = FALSE;
  1372.             if (t_ptr->tval == TV_CLOSED_DOOR) {
  1373.             do_turn = TRUE;
  1374.             if ((m_ptr->monfear) && randint(2) == 1) /* afraid       */
  1375.                 t_ptr->p1 = 0;
  1376.             if (t_ptr->p1 == 0)                      /* Closed door  */
  1377.                 do_move = TRUE;
  1378.             else if (t_ptr->p1 > 0) {             /* Locked doors */
  1379.                 if (randint((m_ptr->hp + 1) * (50 + t_ptr->p1)) <
  1380.                 40 * (m_ptr->hp - 10 - t_ptr->p1))
  1381.                 t_ptr->p1 = 0;
  1382.             } else if (t_ptr->p1 < 0) {             /* Stuck doors  */
  1383.                 if (randint((m_ptr->hp + 1) * (50 - t_ptr->p1)) <
  1384.                 40 * (m_ptr->hp - 10 + t_ptr->p1)) {
  1385.                 msg_print("You hear a door burst open!");
  1386.                 disturb(1, 0);
  1387.                 stuck_door = TRUE;
  1388.                 do_move = TRUE;
  1389.                 }
  1390.             }
  1391.             } else if (t_ptr->tval == TV_SECRET_DOOR) {
  1392.             do_turn = TRUE;
  1393.             do_move = TRUE;
  1394.             }
  1395.             if (do_move) {
  1396.             invcopy(t_ptr, OBJ_OPEN_DOOR);
  1397.             if (stuck_door)    /* 50% chance of breaking door */
  1398.                 t_ptr->p1 = 1 - randint(2);
  1399.             c_ptr->fval = CORR_FLOOR;
  1400.             lite_spot(newy, newx);
  1401.             *rcmove |= CM_OPEN_DOOR;
  1402.             do_move = FALSE;
  1403.             }
  1404.         } else {       /* Creature can not open doors, must bash them   */
  1405.             if (t_ptr->tval == TV_CLOSED_DOOR) {
  1406.             do_turn = TRUE;
  1407.             if (randint((m_ptr->hp + 1) * (80 + MY_ABS(t_ptr->p1))) <
  1408.                 40 * (m_ptr->hp - 20 - MY_ABS(t_ptr->p1))) {
  1409.                 invcopy(t_ptr, OBJ_OPEN_DOOR);
  1410.             /* 50% chance of breaking door */
  1411.                 t_ptr->p1 = 1 - randint(2);
  1412.                 c_ptr->fval = CORR_FLOOR;
  1413.                 lite_spot(newy, newx);
  1414.                 msg_print("You hear a door burst open!");
  1415.                 disturb(1, 0);
  1416.             }
  1417.             }
  1418.         }
  1419.         }
  1420.     /* Glyph of warding present?       */
  1421.         if (do_move && (c_ptr->tptr != 0) &&
  1422.         (t_list[c_ptr->tptr].tval == TV_VIS_TRAP) &&
  1423.         (t_list[c_ptr->tptr].subval == 99)) {
  1424.         if (randint(OBJ_RUNE_PROT) < c_list[m_ptr->mptr].level) {
  1425.             if ((newy == char_row) && (newx == char_col))
  1426.             msg_print("The rune of protection is broken!");
  1427.             (void)delete_object(newy, newx);
  1428.         } else {
  1429.             do_move = FALSE;
  1430. /* If the creature moves only to attack, don't let it move if the glyph
  1431.  * prevents it from attacking */
  1432.             if (movebits & CM_ATTACK_ONLY)
  1433.             do_turn = TRUE;
  1434.         }
  1435.         }
  1436.     /* Creature has attempted to move on player?       */
  1437.         if (do_move)
  1438.         if (c_ptr->cptr == 1) {
  1439.         /*
  1440.          * if the monster is not lit, must call update_mon, it may be
  1441.          * faster than character, and hence could have just moved
  1442.          * next to character this same turn 
  1443.          */
  1444.             if (!m_ptr->ml)
  1445.             update_mon(monptr);
  1446.             make_attack(monptr);
  1447.             do_move = FALSE;
  1448.             do_turn = TRUE;
  1449.         }
  1450.         /* Creature is attempting to move on other creature?       */
  1451.         else if ((c_ptr->cptr > 1) &&
  1452.              ((newy != m_ptr->fy) ||
  1453.               (newx != m_ptr->fx))) {
  1454.             /* Creature eats other creatures?     */
  1455. #ifdef ATARIST_MWC
  1456.             if ((movebits & (holder = CM_EATS_OTHER)) &&
  1457. #else
  1458.             if ((movebits & CM_EATS_OTHER) &&
  1459. #endif
  1460.             (c_list[m_ptr->mptr].mexp >
  1461.              c_list[m_list[c_ptr->cptr].mptr].mexp)) {
  1462.             if (m_list[c_ptr->cptr].ml)
  1463. #ifdef ATARIST_MWC
  1464.                 *rcmove |= holder;
  1465. #else
  1466.                     *rcmove |= CM_EATS_OTHER;
  1467. #endif
  1468.             /* It ate an already processed monster. Handle normally. */
  1469.             if (monptr < c_ptr->cptr)
  1470.                 delete_monster((int)c_ptr->cptr);
  1471.             /*
  1472.              * If it eats this monster, an already processed monster
  1473.              * will take its place, causing all kinds of havoc. 
  1474.              * Delay the kill a bit. 
  1475.              */
  1476.             else
  1477.                 fix1_delete_monster((int)c_ptr->cptr);
  1478.             } else
  1479.             do_move = FALSE;
  1480.             }
  1481.     /* Creature has been allowed move.     */
  1482.         if (do_move) {
  1483.         /* Move creature record               */
  1484.         move_rec((int)m_ptr->fy, (int)m_ptr->fx, newy, newx);
  1485.         if (m_ptr->ml) {
  1486.             m_ptr->ml = FALSE;
  1487.             lite_spot((int)m_ptr->fy, (int)m_ptr->fx);
  1488.         }
  1489.         m_ptr->fy = newy;
  1490.         m_ptr->fx = newx;
  1491.         m_ptr->cdis = distance(char_row, char_col, newy, newx);
  1492.         do_turn = TRUE;
  1493.  
  1494.         /* Pick up or eat an object           */
  1495. #ifdef ATARIST_MWC
  1496.         if (movebits & (holder = CM_PICKS_UP))
  1497. #else
  1498.         if (movebits & CM_PICKS_UP)
  1499. #endif
  1500.         {
  1501. /* used in code to prevent orcs from picking up Slay Orc weapons, etc -CFT */
  1502.             int32u t;
  1503.  
  1504.             c_ptr = &cave[newy][newx];
  1505.  
  1506.             if ((c_ptr->tptr != 0)
  1507.             && (t_list[c_ptr->tptr].tval <= TV_MAX_OBJECT)) {
  1508. #ifdef ATARIST_MWC
  1509.             *rcmove |= holder;
  1510. #else
  1511.             *rcmove |= CM_PICKS_UP;
  1512. #endif
  1513.             t = 0L;
  1514.             if ((t_list[c_ptr->tptr].flags & TR_SLAY_DRAGON) ||
  1515.                 (t_list[c_ptr->tptr].flags & TR_SLAY_X_DRAGON))
  1516.                 t |= DRAGON;
  1517.             if (t_list[c_ptr->tptr].flags & TR_SLAY_UNDEAD)
  1518.                 t |= UNDEAD;
  1519.             if (t_list[c_ptr->tptr].flags2 & TR_SLAY_DEMON)
  1520.                 t |= DEMON;
  1521.             if (t_list[c_ptr->tptr].flags2 & TR_SLAY_TROLL)
  1522.                 t |= TROLL;
  1523.             if (t_list[c_ptr->tptr].flags2 & TR_SLAY_GIANT)
  1524.                 t |= GIANT;
  1525.             if (t_list[c_ptr->tptr].flags2 & TR_SLAY_ORC)
  1526.                 t |= ORC;
  1527.             /* if artifact, or wearable & hurts this monster -CWS */
  1528.             if ((t_list[c_ptr->tptr].flags2 & TR_ARTIFACT) ||
  1529.                 ( (t_list[c_ptr->tptr].tval >= TV_MIN_WEAR) &&
  1530.                   (t_list[c_ptr->tptr].tval <= TV_MAX_WEAR) &&
  1531.                   (c_list[m_ptr->mptr].cdefense & t) )) {
  1532.  
  1533. /* FIXME: should use new line-splitting code */
  1534.  
  1535.                 vtype               m_name, out_val, i_name;
  1536.                 int                 ii, split = (-1);
  1537.  
  1538.                 update_mon(monptr);    /* make sure ml see right -CFT */
  1539.                 if ((m_ptr->ml) && los(char_row, char_col, m_ptr->fy,
  1540.                            m_ptr->fx)) {
  1541.                 /* if we can see it, tell us what happened -CFT */
  1542.                 monster_name(m_name, m_ptr, &(c_list[m_ptr->mptr]));
  1543.                 objdes(i_name, &(t_list[c_ptr->tptr]), TRUE);
  1544.                 sprintf(out_val,
  1545.                     "%s tries to pick up %s, but stops suddenly!",
  1546.                     m_name, i_name);
  1547.                 for (ii = 0; ii < 72 && out_val[ii]; ii++)
  1548.                     if (out_val[ii] == ' ')
  1549.                     split = ii;
  1550.                 if ((ii > 71) && (split != (-1))) {
  1551.                 /* then we should probably split it -CFT */
  1552.                     out_val[split] = 0;
  1553.                     msg_print(out_val);
  1554.                     msg_print(&out_val[split + 1]);
  1555.                 } else
  1556.                /* if ii <= 71, then it'll fit nicely in 1 line.
  1557.                 * Or, we found no space to split at... -CFT */
  1558.                     msg_print(out_val);
  1559.                 } /* if can see */
  1560.             }
  1561.                   /* if shouldn't pick up */ 
  1562.             else
  1563.                 (void)delete_object(newy, newx);
  1564.             }
  1565.         }
  1566.         }
  1567.         }
  1568.     i++;
  1569.     /* Up to 5 attempts at moving,   give up.      */
  1570.     }
  1571.     while ((!do_turn) && (i < 5));
  1572. }
  1573.  
  1574.  
  1575. /* Creatures can cast spells too.  (Dragon Breath)    -RAK-     */
  1576. /* cast_spell = true if creature changes position     */
  1577. /* took_turn  = true if creature casts a spell         */
  1578. static void 
  1579. mon_cast_spell(monptr, took_turn)
  1580. int monptr, *took_turn;
  1581. {
  1582.     int32u                 i;
  1583.     int                    y, x, chance, thrown_spell, r1;
  1584.     register int           k;
  1585.     int                    spell_choice[64], desperate = FALSE;
  1586.     vtype                  cdesc, outval, ddesc;
  1587.     register struct flags  *f_ptr;
  1588.     register monster_type  *m_ptr;
  1589.     register creature_type *r_ptr;
  1590.     char                   sex;
  1591.     int                    blind = (py.flags.blind > 0);
  1592. /* alter msgs if player can't see -CFT */
  1593.  
  1594.     if (death)
  1595.     return;
  1596.  
  1597.     m_ptr = &m_list[monptr];
  1598.     r_ptr = &c_list[m_ptr->mptr];
  1599.     sex = r_ptr->gender;
  1600. /* 1 in x chance of casting spell           */
  1601.     chance = (int)(r_ptr->spells & CS_FREQ);
  1602.     if (chance == 0) {
  1603.     msg_print("CHANCE == 0");
  1604.     msg_print("caused by ....");
  1605.     msg_print(r_ptr->name);
  1606.     *took_turn = FALSE;
  1607.     } else if (randint(chance) != 1)
  1608.     *took_turn = FALSE;
  1609. /* Must be within certain range           */
  1610.     else if (m_ptr->cdis > MAX_SPELL_DIS)
  1611.     *took_turn = FALSE;
  1612. /* Must have unobstructed Line-Of-Sight     (reversed direction -CWS)  */
  1613.     else if (!los((int)m_ptr->fy, (int)m_ptr->fx, char_row, char_col))
  1614.     *took_turn = FALSE;
  1615.     else {               /* Creature is going to cast a spell     */
  1616.     *took_turn = TRUE;
  1617.     /* Check to see if monster should be lit. */
  1618.     update_mon(monptr);
  1619.     /* Describe the attack                   */
  1620.     if (m_ptr->ml) {
  1621.         if (r_ptr->cdefense & UNIQUE)
  1622.         (void)sprintf(cdesc, "%s ", r_ptr->name);
  1623.         else
  1624.         (void)sprintf(cdesc, "The %s ", r_ptr->name);
  1625.     } else
  1626.         (void)strcpy(cdesc, "It ");
  1627.     /* For "DIED_FROM" string     */
  1628.     if (UNIQUE & r_ptr->cdefense)
  1629.         (void)sprintf(ddesc, "%s", r_ptr->name);
  1630.     else if (is_a_vowel(r_ptr->name[0]))
  1631.         (void)sprintf(ddesc, "an %s", r_ptr->name);
  1632.     else
  1633.         (void)sprintf(ddesc, "a %s", r_ptr->name);
  1634.     /* End DIED_FROM               */
  1635.  
  1636.     /* Extract all possible spells into spell_choice */
  1637.     if ((r_ptr->cdefense & INTELLIGENT) &&
  1638.         (m_ptr->hp < ((r_ptr->hd[0] * r_ptr->hd[1]) / 10)) &&
  1639.         (r_ptr->spells & CS_INT1 || r_ptr->spells2 & CS_INT2 ||
  1640.          r_ptr->spells3 & CS_INT3) && randint(2) == 1) {
  1641.         desperate = TRUE;
  1642.         c_recall[m_ptr->mptr].r_cdefense |= INTELLIGENT;
  1643.     }
  1644.     i = (r_ptr->spells & ~CS_FREQ);
  1645.     if (desperate)
  1646.         i &= CS_INT1;
  1647.     k = 0;
  1648.     while (i != 0) {
  1649.         spell_choice[k] = bit_pos(&i);
  1650.         k++;
  1651.     }
  1652.     i = r_ptr->spells2;
  1653.     if (desperate)
  1654.         i &= CS_INT2;
  1655.     while (i != 0) {
  1656.         spell_choice[k] = bit_pos(&i) + 32;
  1657.         k++;
  1658.     }
  1659.     i = r_ptr->spells3;
  1660.     if (desperate)
  1661.         i &= CS_INT3;
  1662.     while (i != 0) {
  1663.         spell_choice[k] = bit_pos(&i) + 64;
  1664.         k++;
  1665.     }
  1666.     /* Choose a spell to cast                   */
  1667.     if (!k)
  1668.         thrown_spell = 200;
  1669.     else
  1670.         thrown_spell = spell_choice[randint(k) - 1];
  1671.     thrown_spell++;
  1672.     /* all except teleport_away() and drain mana spells always disturb */
  1673.     if (thrown_spell > 6 && thrown_spell != 7)
  1674.         disturb(1, 0);
  1675.     /* Cast the spell.                 */
  1676.     switch (thrown_spell) {
  1677.       case 5:           /* Teleport Short */
  1678.         (void)strcat(cdesc, "blinks away.");
  1679.         msg_print(cdesc);
  1680.         teleport_away(monptr, 5);
  1681.         break;
  1682.       case 6:           /* Teleport Long */
  1683.         (void)strcat(cdesc, "teleports away.");
  1684.         msg_print(cdesc);
  1685.         teleport_away(monptr, MAX_SIGHT);
  1686.         break;
  1687.       case 7:           /* Teleport To     */
  1688.         (void)strcat(cdesc, "commands you to return!");
  1689.         msg_print(cdesc);
  1690.         teleport_to((int)m_ptr->fy, (int)m_ptr->fx);
  1691.         break;
  1692.       case 8:           /* Light Wound     */
  1693.         if (!blind)
  1694.         (void)strcat(cdesc, "points at you and curses.");
  1695.         else
  1696.         (void)strcat(cdesc, "mumbles.");
  1697.         msg_print(cdesc);
  1698.         if (player_saves())
  1699.         msg_print("You resist the effects of the spell.");
  1700.         else
  1701.         take_hit(damroll(3, 8), ddesc);
  1702.         break;
  1703.       case 9:           /* Serious Wound */
  1704.         if (!blind)
  1705.         (void)strcat(cdesc, "points at you and curses horribly.");
  1706.         else
  1707.         (void)strcat(cdesc, "mumbles.");
  1708.         msg_print(cdesc);
  1709.         if (player_saves())
  1710.         msg_print("You resist the effects of the spell.");
  1711.         else
  1712.         take_hit(damroll(8, 8), ddesc);
  1713.         break;
  1714.       case 10:           /* Hold Person      */
  1715.         if (!blind)
  1716.         (void)strcat(cdesc, "gazes deep into your eyes!");
  1717.         else
  1718.         (void)strcat(cdesc,
  1719.                  "mumbles, and you feel something holding you!");
  1720.         msg_print(cdesc);
  1721.         if (py.flags.free_act)
  1722.         msg_print("You are unaffected.");
  1723.         else if (player_saves())
  1724.         if (!blind)
  1725.             msg_print("You stare back unafraid!");
  1726.         else
  1727.             msg_print("You resist!");
  1728.         else if (py.flags.paralysis > 0)
  1729.         py.flags.paralysis += 2;
  1730.         else
  1731.         py.flags.paralysis = randint(5) + 4;
  1732.         break;
  1733.       case 11:           /* Cause Blindness */
  1734.         if (!blind)
  1735.         (void)strcat(cdesc, "casts a spell, burning your eyes!");
  1736.         else
  1737.         (void)strcat(cdesc, "mumbles, and your eyes burn even more.");
  1738.         msg_print(cdesc);
  1739.         if ((player_saves()) || (py.flags.blindness_resist))
  1740.         if (!blind)
  1741.             msg_print("You blink and your vision clears.");
  1742.         else
  1743.             msg_print("But the extra burning quickly fades away.");
  1744.         else if (py.flags.blind > 0)
  1745.         py.flags.blind += 6;
  1746.         else
  1747.         py.flags.blind += 12 + randint(3);
  1748.         break;
  1749.       case 12:           /* Cause Confuse */
  1750.         if (!blind)
  1751.         (void)strcat(cdesc, "creates a mesmerising illusion.");
  1752.         else
  1753.         (void)strcat(cdesc, "mumbles, and you hear puzzling noises.");
  1754.         msg_print(cdesc);
  1755.         if ((player_saves()) || (py.flags.confusion_resist)
  1756.         || (py.flags.chaos_resist))
  1757.         msg_print("You disbelieve the feeble spell.");
  1758.         else if (py.flags.confused > 0)
  1759.         py.flags.confused += 2;
  1760.         else
  1761.         py.flags.confused = randint(5) + 3;
  1762.         break;
  1763.       case 13:           /* Cause Fear      */
  1764.         if (!blind)
  1765.         (void)strcat(cdesc, "casts a fearful illusion.");
  1766.         else
  1767.         (void)strcat(cdesc, "mumbles, and you hear scary noises.");
  1768.         msg_print(cdesc);
  1769.         if (player_saves() || py.flags.fear_resist)
  1770.         msg_print("You refuse to be frightened.");
  1771.         else if (py.flags.afraid > 0)
  1772.         py.flags.afraid += 2;
  1773.         else
  1774.         py.flags.afraid = randint(5) + 3;
  1775.         break;
  1776.       case 14:           /* Summon Monster */
  1777.         if (!blind)
  1778.         (void)strcat(cdesc, "magically summons help!");
  1779.         else
  1780.         (void)strcat(cdesc,
  1781.                  "mumbles, and you hear something appear nearby.");
  1782.         msg_print(cdesc);
  1783.         y = char_row;
  1784.         x = char_col;
  1785.     /* in case compact_monster() is called,it needs monptr */
  1786.         hack_monptr = monptr;
  1787.         (void)summon_monster(&y, &x, FALSE);
  1788.         hack_monptr = (-1);
  1789.         update_mon((int)cave[y][x].cptr);
  1790.         break;
  1791.       case 15:           /* Summon Undead */
  1792.         if (!blind)
  1793.         (void)strcat(cdesc,
  1794.                  "magically summons help from beyond the grave!");
  1795.         else
  1796.         (void)strcat(cdesc,
  1797.              "mumbles, and you hear something creepy appear nearby.");
  1798.         msg_print(cdesc);
  1799.         y = char_row;
  1800.         x = char_col;
  1801.     /* in case compact_monster() is called,it needs monptr */
  1802.         hack_monptr = monptr;
  1803.         (void)summon_undead(&y, &x);
  1804.         hack_monptr = (-1);
  1805.         update_mon((int)cave[y][x].cptr);
  1806.         break;
  1807.       case 16:           /* Slow Person     */
  1808.         (void)strcat(cdesc, "drains power from your muscles!");
  1809.         msg_print(cdesc);
  1810.         if (py.flags.free_act)
  1811.         msg_print("You are unaffected.");
  1812.         else if (player_saves())
  1813.         msg_print("Your body resists the spell.");
  1814.         else if (py.flags.slow > 0)
  1815.         py.flags.slow += 2;
  1816.         else
  1817.         py.flags.slow = randint(5) + 3;
  1818.         break;
  1819.       case 17:           /* Drain Mana     */
  1820.         if (py.misc.cmana > 0) {
  1821.         disturb(1, 0);
  1822.         (void)sprintf(outval,
  1823.                   "%sdraws psychic energy from you!", cdesc);
  1824.         msg_print(outval);
  1825.         if (m_ptr->ml) {
  1826.             (void)sprintf(outval, "%sappears healthier.", cdesc);
  1827.             msg_print(outval);
  1828.         }
  1829.         r1 = (randint((int)r_ptr->level) >> 1) + 1;
  1830.         if (r1 > py.misc.cmana) {
  1831.             r1 = py.misc.cmana;
  1832.             py.misc.cmana = 0;
  1833.             py.misc.cmana_frac = 0;
  1834.         } else
  1835.             py.misc.cmana -= r1;
  1836.         prt_cmana();
  1837.         m_ptr->hp += 6 * (r1);
  1838.         }
  1839.         break;
  1840.       case 18:           /* Summon Demon */
  1841.         if (!blind)
  1842.         (void)strcat(cdesc, "summons a hellish adversary!");
  1843.         else
  1844.         (void)strcat(cdesc,
  1845.              "mumbles, and you smell fire and brimstone nearby.");
  1846.         msg_print(cdesc);
  1847.         y = char_row;
  1848.         x = char_col;
  1849.     /* in case compact_monster() is called,it needs monptr */
  1850.         hack_monptr = monptr;
  1851.         (void)summon_demon(c_list[m_ptr->mptr].level, &y, &x);
  1852.         hack_monptr = (-1);
  1853.         update_mon((int)cave[y][x].cptr);
  1854.         break;
  1855.       case 19:           /* Summon Dragon */
  1856.         if (!blind)
  1857.         (void)strcat(cdesc, "magically summons a Dragon!");
  1858.         else
  1859.         (void)strcat(cdesc,
  1860.               "mumbles, and you hear something large appear nearby.");
  1861.         msg_print(cdesc);
  1862.         y = char_row;
  1863.         x = char_col;
  1864.     /* in case compact_monster() is called,it needs monptr */
  1865.         hack_monptr = monptr;
  1866.         (void)summon_dragon(&y, &x);
  1867.         hack_monptr = (-1);
  1868.         update_mon((int)cave[y][x].cptr);
  1869.         break;
  1870.       case 20:           /* Breath Light */
  1871.         if (!blind)
  1872.         (void)strcat(cdesc, "breathes lightning.");
  1873.         else
  1874.         (void)strcat(cdesc, "breathes, and you get zapped.");
  1875.         msg_print(cdesc);
  1876.         breath(GF_LIGHTNING, char_row, char_col,
  1877.            ((m_ptr->hp / 3) > 1600 ? 1600 : (m_ptr->hp / 3)),
  1878.            ddesc, monptr);
  1879.         break;
  1880.       case 21:           /* Breath Gas     */
  1881.         if (!blind)
  1882.         (void)strcat(cdesc, "breathes gas.");
  1883.         else
  1884.         (void)strcat(cdesc, "breathes, and you inhale noxious gases.");
  1885.         msg_print(cdesc);
  1886.         breath(GF_POISON_GAS, char_row, char_col,
  1887.         ((m_ptr->hp / 3) > 800 ? 800 : (m_ptr->hp / 3)), ddesc, monptr);
  1888.         break;
  1889.       case 22:           /* Breath Acid     */
  1890.         if (!blind)
  1891.         (void)strcat(cdesc, "breathes acid.");
  1892.         else
  1893.         (void)strcat(cdesc, "breathes, and your skin is burning.");
  1894.         msg_print(cdesc);
  1895.         breath(GF_ACID, char_row, char_col,
  1896.            ((m_ptr->hp / 3) > 1600 ? 1600 : (m_ptr->hp / 3)),
  1897.            ddesc, monptr);
  1898.         break;
  1899.       case 23:           /* Breath Frost */
  1900.         if (!blind)
  1901.         (void)strcat(cdesc, "breathes frost.");
  1902.         else
  1903.         (void)strcat(cdesc, "breathes, and feel a frigid blast.");
  1904.         msg_print(cdesc);
  1905.         breath(GF_FROST, char_row, char_col,
  1906.            ((m_ptr->hp / 3) > 1600 ? 1600 : (m_ptr->hp / 3)),
  1907.            ddesc, monptr);
  1908.         break;
  1909.       case 24:           /* Breath Fire     */
  1910.         if (!blind)
  1911.         (void)strcat(cdesc, "breathes fire.");
  1912.         else
  1913.         (void)strcat(cdesc, "breathes, and you're on fire.");
  1914.         msg_print(cdesc);
  1915.         breath(GF_FIRE, char_row, char_col,
  1916.            ((m_ptr->hp / 3) > 1600 ? 1600 : (m_ptr->hp / 3)),
  1917.            ddesc, monptr);
  1918.         break;
  1919.       case 25:           /* Fire Bolt */
  1920.         if (!blind)
  1921.         (void)strcat(cdesc, "casts a Fire bolt.");
  1922.         else
  1923.         (void)strcat(cdesc, "mumbles.");
  1924.         msg_print(cdesc);
  1925.         bolt(GF_FIRE, char_row, char_col,
  1926.          damroll(9, 8) + (c_list[m_ptr->mptr].level / 3)
  1927.          ,ddesc, m_ptr, monptr);
  1928.         break;
  1929.       case 26:           /* Frost Bolt */
  1930.         if (!blind)
  1931.         (void)strcat(cdesc, "casts a Frost bolt.");
  1932.         else
  1933.         (void)strcat(cdesc, "mumbles, and you feel a frigid blast .");
  1934.         msg_print(cdesc);
  1935.         bolt(GF_FROST, char_row, char_col,
  1936.          damroll(6, 8) + (c_list[m_ptr->mptr].level / 3)
  1937.          ,ddesc, m_ptr, monptr);
  1938.         break;
  1939.       case 27:           /* Acid Bolt */
  1940.         if (!blind)
  1941.         (void)strcat(cdesc, "casts a Acid bolt.");
  1942.         else
  1943.         (void)strcat(cdesc, "mumbles, and your skin burns.");
  1944.         msg_print(cdesc);
  1945.         bolt(GF_ACID, char_row, char_col,
  1946.          damroll(7, 8) + (c_list[m_ptr->mptr].level / 3)
  1947.          ,ddesc, m_ptr, monptr);
  1948.         break;
  1949.       case 28:           /* Magic Missiles */
  1950.         if (!blind)
  1951.         (void)strcat(cdesc, "casts a Magic missile.");
  1952.         else
  1953.         (void)strcat(cdesc, "mumbles, and you feel an arrow hit you.");
  1954.         msg_print(cdesc);
  1955.         bolt(GF_MAGIC_MISSILE, char_row, char_col,
  1956.          damroll(2, 6) + (c_list[m_ptr->mptr].level / 3)
  1957.          ,ddesc, m_ptr, monptr);
  1958.         break;
  1959.       case 29:           /* Critical Wound     */
  1960.         if (!blind)
  1961.         (void)strcat(cdesc, "points at you, incanting terribly!");
  1962.         else
  1963.         (void)strcat(cdesc, "mumbles loudly.");
  1964.         msg_print(cdesc);
  1965.         if (player_saves())
  1966.         msg_print("You resist the effects of the spell.");
  1967.         else
  1968.         take_hit(damroll(10, 15), ddesc);
  1969.         break;
  1970.       case 30:           /* Fire Ball */
  1971.         if (!blind)
  1972.         (void)strcat(cdesc, "casts a Fire ball.");
  1973.         else
  1974.         (void)strcat(cdesc, "mumbles, and you're on fire.");
  1975.         msg_print(cdesc);
  1976.         breath(GF_FIRE, char_row, char_col,
  1977.            randint((c_list[m_ptr->mptr].level * 7) / 2) + 10,
  1978.            ddesc, monptr);
  1979.         break;
  1980.       case 31:           /* Frost Ball */
  1981.         if (!blind)
  1982.         (void)strcat(cdesc, "casts a Frost ball.");
  1983.         else
  1984.         (void)strcat(cdesc, "mumbles, and you feel a frigid blast.");
  1985.         msg_print(cdesc);
  1986.         breath(GF_FROST, char_row, char_col,
  1987.            randint((c_list[m_ptr->mptr].level * 3) / 2) + 10,
  1988.            ddesc, monptr);
  1989.         break;
  1990.       case 32:           /* Mana Bolt */
  1991.         if (!blind)
  1992.         (void)strcat(cdesc, "casts a Mana bolt.");
  1993.         else
  1994.         (void)strcat(cdesc, "mumbles, and you feel a magical blast.");
  1995.         msg_print(cdesc);
  1996.         bolt(GF_MAGIC_MISSILE, char_row, char_col,
  1997.         randint((c_list[m_ptr->mptr].level * 7) / 2) + 50, ddesc, m_ptr,
  1998.          monptr);
  1999.         break;
  2000.       case 33:
  2001.         if (!blind)
  2002.         (void)strcat(cdesc, "breathes chaos.");
  2003.         else
  2004.         (void)strcat(cdesc, "breathes, and you feel a strange flux.");
  2005.         msg_print(cdesc);
  2006.         breath(GF_CHAOS, char_row, char_col,
  2007.         ((m_ptr->hp / 6) > 600 ? 600 : (m_ptr->hp / 6)), ddesc, monptr);
  2008.         break;
  2009.       case 34:
  2010.         if (!blind)
  2011.         (void)strcat(cdesc, "breathes shards.");
  2012.         else
  2013.         (void)strcat(cdesc, "breathes, and sharp fragments cut you.");
  2014.         msg_print(cdesc);
  2015.         breath(GF_SHARDS, char_row, char_col,
  2016.         ((m_ptr->hp / 6) > 400 ? 400 : (m_ptr->hp / 6)), ddesc, monptr);
  2017.         break;
  2018.       case 35:
  2019.         if (!blind)
  2020.         (void)strcat(cdesc, "breathes sound.");
  2021.         else
  2022.         (void)strcat(cdesc, "breathes, and you are deafened.");
  2023.         msg_print(cdesc);
  2024.         breath(GF_SOUND, char_row, char_col,
  2025.         ((m_ptr->hp / 6) > 400 ? 400 : (m_ptr->hp / 6)), ddesc, monptr);
  2026.         break;
  2027.       case 36:
  2028.         if (!blind)
  2029.         (void)strcat(cdesc, "breathes confusion.");
  2030.         else
  2031.         (void)strcat(cdesc, "breathes, and you feel dizzy.");
  2032.         msg_print(cdesc);
  2033.         breath(GF_CONFUSION, char_row, char_col,
  2034.         ((m_ptr->hp / 6) > 400 ? 400 : (m_ptr->hp / 6)), ddesc, monptr);
  2035.         break;
  2036.       case 37:
  2037.         if (!blind)
  2038.         (void)strcat(cdesc, "breathes disenchantment.");
  2039.         else
  2040.         (void)strcat(cdesc,
  2041.              "breathes, and your equipment seems less powerful.");
  2042.         msg_print(cdesc);
  2043.         breath(GF_DISENCHANT, char_row, char_col,
  2044.         ((m_ptr->hp / 6) > 500 ? 500 : (m_ptr->hp / 6)), ddesc, monptr);
  2045.         break;
  2046.       case 38:
  2047.         if (!blind)
  2048.         (void)strcat(cdesc, "breathes nether.");
  2049.         else
  2050.         (void)strcat(cdesc, "breathes, and you feel an unholy aura.");
  2051.         msg_print(cdesc);
  2052.         breath(GF_NETHER, char_row, char_col,
  2053.         ((m_ptr->hp / 6) > 550 ? 550 : (m_ptr->hp / 6)), ddesc, monptr);
  2054.         break;
  2055.       case 39:
  2056.         if (!blind)
  2057.         (void)strcat(cdesc, "casts a Lightning bolt.");
  2058.         else
  2059.         (void)strcat(cdesc, "mumbles.");
  2060.         msg_print(cdesc);
  2061.         bolt(GF_LIGHTNING, char_row, char_col,
  2062.          damroll(4, 8) + (c_list[m_ptr->mptr].level / 3)
  2063.          ,ddesc, m_ptr, monptr);
  2064.         break;
  2065.       case 40:
  2066.         if (!blind)
  2067.         (void)strcat(cdesc, "casts a Lightning Ball.");
  2068.         else
  2069.         (void)strcat(cdesc, "mumbles, and you get zapped.");
  2070.         msg_print(cdesc);
  2071.         breath(GF_LIGHTNING, char_row, char_col,
  2072.         randint((c_list[m_ptr->mptr].level * 3) / 2) + 8, ddesc, monptr);
  2073.         break;
  2074.       case 41:
  2075.         if (!blind)
  2076.         (void)strcat(cdesc, "casts an Acid Ball.");
  2077.         else
  2078.         (void)strcat(cdesc, "mumbles, and your skin is burning.");
  2079.         msg_print(cdesc);
  2080.         breath(GF_ACID, char_row, char_col,
  2081.         randint(c_list[m_ptr->mptr].level * 3) + 15, ddesc, monptr);
  2082.         break;
  2083.       case 42:
  2084.         if (!blind)
  2085.         (void)strcat(cdesc, "casts a spell and cackles evilly.");
  2086.         else
  2087.         (void)strcat(cdesc, "mumbles, and then cackles evilly.");
  2088.         msg_print(cdesc);
  2089.         (void)trap_creation();
  2090.         break;
  2091.       case 43:
  2092.         if (!blind)
  2093.         (void)strcat(cdesc, "points at you, screaming the word DIE!");
  2094.         else
  2095.         (void)strcat(cdesc, "mumbles, and then screams 'DIE!'.");
  2096.         msg_print(cdesc);
  2097.         if (player_saves())
  2098.         msg_print("You laugh at the feeble spell.");
  2099.         else {
  2100.         msg_print("You start to bleed!");
  2101.         take_hit(damroll(15, 15), ddesc);
  2102.         cut_player(m_ptr->hp);
  2103.         }
  2104.         break;
  2105.       case 44:
  2106.         if (!blind) {
  2107.         (void)strcat(cdesc, "stares at you.");
  2108.         msg_print(cdesc);
  2109.         } else
  2110.         msg_print("You feel something focusing on your mind.");
  2111.  
  2112.         if (player_saves())
  2113.         msg_print("You resist the effects.");
  2114.         else {
  2115.         msg_print("Your mind is blasted by psionic energy.");
  2116.         if ((!py.flags.confusion_resist) && (!py.flags.chaos_resist)) {
  2117.             if (py.flags.confused > 0)
  2118.             py.flags.confused += 2;
  2119.             else
  2120.             py.flags.confused = randint(5) + 3;
  2121.         }
  2122.         take_hit(damroll(8, 8), ddesc);
  2123.         }
  2124.         break;
  2125.       case 45:
  2126.         (void)strcat(cdesc, "teleports you away.");
  2127.         msg_print(cdesc);
  2128.         (void)teleport(100);
  2129.         break;
  2130.       case 46:           /* healing, added monster fear code -CWS */
  2131.         if (!blind)
  2132.         (void)sprintf(outval, "%sconcentrates on %s wounds.", cdesc,
  2133.                   (sex == 'm' ? "his" : sex == 'f' ? "her"
  2134.                    : sex == 'p' ? "their" : "its"));
  2135.         else
  2136.         (void)sprintf(outval, "%smumbles to itself.", cdesc);
  2137.         msg_print(outval);
  2138.         monster_is_afraid = 0;
  2139.         if (m_ptr->maxhp == 0) {    /* then we're just going to fix it!
  2140.                      * -CFT */
  2141.         if ((c_list[m_ptr->mptr].cdefense & MAX_HP) || be_nasty)
  2142.             m_ptr->maxhp = max_hp(c_list[m_ptr->mptr].hd);
  2143.         else
  2144.             m_ptr->maxhp = pdamroll(c_list[m_ptr->mptr].hd);
  2145.         }
  2146.         if (!blind) /* if we bother to say "mumbles" above, then shouldn't
  2147.                          * see it heal itself -CFT
  2148.              */
  2149.         strcat(cdesc, "looks ");
  2150.         else
  2151.         strcat(cdesc, "sounds ");
  2152.  
  2153.         if (m_ptr->hp >= m_ptr->maxhp) {
  2154. /* need >= because, if we recalc-ed maxhp, we might have gotten a low roll,
  2155.  * which could be below hp -CFT
  2156.  */
  2157.         (void)strcat(cdesc, "looks as healthy as can be.");
  2158.         msg_print(cdesc);
  2159.         if (m_ptr->monfear > 0) {    /* can't be afraid at max hp's */
  2160.             m_ptr->monfear = 0;
  2161.             monster_is_afraid = (-1);
  2162.         }
  2163.         } else {
  2164.         m_ptr->hp += (c_list[m_ptr->mptr].level) * 6;
  2165.         if (m_ptr->hp > m_ptr->maxhp)
  2166.             m_ptr->hp = m_ptr->maxhp;
  2167.         if (m_ptr->hp == m_ptr->maxhp) {
  2168.             (void)strcat(cdesc, "looks REALLY healthy!");
  2169.             if (m_ptr->monfear > 0) {    /* can't be afraid at max
  2170.                          * hp's */
  2171.             m_ptr->monfear = 0;
  2172.             monster_is_afraid = (-1);
  2173.             }
  2174.         } else {
  2175.             (void)strcat(cdesc, "looks healthier.");
  2176.             if ((m_ptr->monfear > 0) && (m_ptr->maxhp / (m_ptr->hp + 1) < 3)) {
  2177.             m_ptr->monfear = 0;    /* has recovered 33% of it's
  2178.                          * hit points */
  2179.             monster_is_afraid = (-1);
  2180.             }
  2181.         }
  2182.         msg_print(cdesc);
  2183.  
  2184.         if (monster_is_afraid == -1) {    /* no longer afraid -CWS */
  2185.             vtype               m_name, out_val;
  2186.  
  2187.             monster_name(m_name, m_ptr, &c_list[m_ptr->mptr]);
  2188.             sprintf(out_val, "%s recovers %s courage.", m_name,
  2189.                 (sex == 'm' ? "his" : sex == 'f' ? "her" :
  2190.                  sex == 'p' ? "their" : "its"));
  2191.             msg_print(out_val);
  2192.         }
  2193.         }
  2194.         break;
  2195.       case 47:
  2196.         if (!blind)
  2197.         (void)sprintf(outval, "%scasts a spell.", cdesc);
  2198.         else
  2199.         (void)sprintf(outval, "%smumbles to %sself.", cdesc,
  2200.                   (sex == 'm' ? "him" : sex == 'f' ? "her" :
  2201.                    sex == 'p' ? "them" : "it"));
  2202.         msg_print(outval);
  2203.         if ((m_ptr->cspeed) <= ((int)(c_list[m_ptr->mptr].speed) - 10)) {
  2204.         if ((c_list[m_ptr->mptr].speed) <= 15) {
  2205.             (void)strcat(cdesc, "starts moving faster.");
  2206.             msg_print(cdesc);
  2207.             m_ptr->cspeed += 1;
  2208.         }
  2209.         }
  2210.         break;
  2211.       case 48:
  2212.         if (!blind)
  2213.         (void)strcat(cdesc, "fires missiles at you.");
  2214.         else
  2215.         (void)strcat(cdesc, "sounds like it threw something.");
  2216.         msg_print(cdesc);
  2217.         bolt(GF_ARROW, char_row, char_col,
  2218.          damroll(6, 7), ddesc, m_ptr, monptr);
  2219.         break;
  2220.       case 49:
  2221.         if (!blind)
  2222.         (void)strcat(cdesc, "casts a Plasma Bolt.");
  2223.         else
  2224.         (void)strcat(cdesc,
  2225.                  "mumbles, and you are hit with a hellish blast.");
  2226.         msg_print(cdesc);
  2227.         bolt(GF_PLASMA, char_row, char_col,
  2228.          10 + damroll(8, 7) + (c_list[m_ptr->mptr].level),
  2229.          ddesc, m_ptr, monptr);
  2230.         break;
  2231.       case 50:
  2232.         if (!blind)
  2233.         (void)strcat(cdesc, "magically summons monsters!");
  2234.         else
  2235.         (void)strcat(cdesc,
  2236.               "mumbles, and you hear many things appear nearby.");
  2237.         msg_print(cdesc);
  2238.         y = char_row;
  2239.         x = char_col;
  2240.     /* in case compact_monster() is called,it needs monptr */
  2241.         for (k = 0; k < 8; k++) {
  2242.         hack_monptr = monptr;
  2243.         (void)summon_monster(&y, &x, FALSE);
  2244.         hack_monptr = (-1);
  2245.         update_mon((int)cave[y][x].cptr);
  2246.         }
  2247.         break;
  2248.       case 51:
  2249.         if (!blind)
  2250.         (void)strcat(cdesc, "casts a Nether Bolt.");
  2251.         else
  2252.         (void)strcat(cdesc, "mumbles.");
  2253.         msg_print(cdesc);
  2254.         bolt(GF_NETHER, char_row, char_col,
  2255.          30 + damroll(5, 5) + (c_list[m_ptr->mptr].level * 3) / 2,
  2256.          ddesc, m_ptr, monptr);
  2257.         break;
  2258.       case 52:
  2259.         if (!blind)
  2260.         (void)strcat(cdesc, "casts an Ice Bolt.");
  2261.         else
  2262.         (void)strcat(cdesc, "mumbles.");
  2263.         msg_print(cdesc);
  2264.         bolt(GF_FROST, char_row, char_col,
  2265.          damroll(6, 6) + (c_list[m_ptr->mptr].level)
  2266.          ,ddesc, m_ptr, monptr);
  2267.         break;
  2268.       case 53:
  2269.         if (!blind)
  2270.         (void)strcat(cdesc, "gestures in shadow.");
  2271.         else
  2272.         (void)strcat(cdesc, "mumbles.");
  2273.         msg_print(cdesc);
  2274.         (void)unlight_area(char_row, char_col);
  2275.         break;
  2276.       case 54:
  2277.         (void)strcat(cdesc, "tries to blank your mind.");
  2278.         msg_print(cdesc);
  2279.         if (player_saves() || randint(2) == 1)
  2280.         msg_print("You resist the spell.");
  2281.         else if (lose_all_info())
  2282.         msg_print("Your memories fade away.");
  2283.         break;
  2284.       case 55:
  2285.         if (!blind) {
  2286.         (void)sprintf(outval, "%sconcentrates and %s eyes glow red.",
  2287.                   cdesc,
  2288.                   (sex == 'm' ? "his" : sex == 'f' ? "her" :
  2289.                    sex == 'p' ? "their" : "its"));
  2290.         msg_print(outval);
  2291.         } else
  2292.         msg_print("You feel something focusing on your mind.");
  2293.         if (player_saves())
  2294.         if (!blind)
  2295.             msg_print("You avert your gaze!");
  2296.         else
  2297.             msg_print("You resist the effects.");
  2298.         else {
  2299.         msg_print("Your mind is blasted by psionic energy.");
  2300.         take_hit(damroll(12, 15), ddesc);
  2301.         if ((!py.flags.confusion_resist) && (!py.flags.chaos_resist)) {
  2302.             if (py.flags.confused > 0)
  2303.             py.flags.confused += 2;
  2304.             else
  2305.             py.flags.confused = randint(5) + 3;
  2306.         }
  2307.         if (!py.flags.free_act) {
  2308.             if (py.flags.paralysis > 0)
  2309.             py.flags.paralysis += 2;
  2310.             else
  2311.             py.flags.paralysis = randint(5) + 4;
  2312.             if (py.flags.slow > 0)
  2313.             py.flags.slow += 2;
  2314.             else
  2315.             py.flags.slow = randint(5) + 3;
  2316.         }
  2317.         if (!py.flags.blindness_resist) {
  2318.             if (py.flags.blind > 0)
  2319.             py.flags.blind += 6;
  2320.             else
  2321.             py.flags.blind += 12 + randint(3);
  2322.         }
  2323.         }
  2324.         break;
  2325.       case 56:
  2326.         if (!blind)
  2327.         (void)strcat(cdesc, "casts a Stinking Cloud.");
  2328.         else
  2329.         (void)strcat(cdesc, "mumbles, and you smell a foul odor.");
  2330.         msg_print(cdesc);
  2331.         breath(GF_POISON_GAS, char_row, char_col,
  2332.            damroll(12, 2), ddesc, monptr);
  2333.         break;
  2334.       case 57:
  2335.         if (!blind)
  2336.         (void)strcat(cdesc, "gestures at you.");
  2337.         else
  2338.         (void)strcat(cdesc, "mumbles strangely.");
  2339.         msg_print(cdesc);
  2340.         if ((player_saves()) || (randint(3) != 1) ||
  2341.         (py.flags.nexus_resist))
  2342.         msg_print("You keep your feet firmly on the ground.");
  2343.         else {
  2344.         k = dun_level;
  2345.         if (dun_level == Q_PLANE)
  2346.             dun_level = 0;
  2347.         else if (is_quest(dun_level))
  2348.             dun_level -= 1;
  2349.         else
  2350.             dun_level += (-3) + 2 * randint(2);
  2351.         if (dun_level < 0)
  2352.             dun_level = 0;
  2353.         if (k == Q_PLANE)
  2354.             msg_print("You warp through a cross-dimension gate.");
  2355.         else if (k < dun_level)
  2356.             msg_print("You sink through the floor.");
  2357.         else
  2358.             msg_print("You rise up through the ceiling.");
  2359.         new_level_flag = TRUE;
  2360.         }
  2361.         break;
  2362.       case 58:
  2363.         f_ptr = (&py.flags);
  2364.         if (!blind)
  2365.         (void)strcat(cdesc, "casts a Water Bolt.");
  2366.         else
  2367.         (void)strcat(cdesc, "mumbles.");
  2368.         msg_print(cdesc);
  2369.         bolt(GF_WATER, char_row, char_col,
  2370.          damroll(10, 10) + (c_list[m_ptr->mptr].level)
  2371.          ,ddesc, m_ptr, monptr);
  2372.         break;
  2373.       case 59:
  2374.         f_ptr = &py.flags;
  2375.         if (!blind)
  2376.         (void)strcat(cdesc, "gestures fluidly.");
  2377.         else
  2378.         (void)strcat(cdesc, "mumbles.");
  2379.         msg_print(cdesc);
  2380.         msg_print("You are engulfed in a whirlpool.");
  2381.         breath(GF_WATER, char_row, char_col,
  2382.            randint((c_list[m_ptr->mptr].level * 5) / 2) + 50,
  2383.            ddesc, monptr);
  2384.         break;
  2385.       case 60:
  2386.         if (!blind)
  2387.         (void)strcat(cdesc, "casts a Nether Ball.");
  2388.         else
  2389.         (void)strcat(cdesc, "mumbles, and you feel an unholy aura.");
  2390.         msg_print(cdesc);
  2391.         breath(GF_NETHER, char_row, char_col,
  2392.            (50 + damroll(10, 10) + (c_list[m_ptr->mptr].level)),
  2393.            ddesc, monptr);
  2394.         break;
  2395.       case 61:
  2396.         if (!blind)
  2397.         (void)strcat(cdesc, "summons an Angel.");
  2398.         else
  2399.         (void)strcat(cdesc,
  2400.                  "mumbles, and you hear something appear nearby.");
  2401.         msg_print(cdesc);
  2402.         y = char_row;
  2403.         x = char_col;
  2404.     /* in case compact_monster() is called,it needs monptr */
  2405.         hack_monptr = monptr;
  2406.         (void)summon_angel(&y, &x);
  2407.         hack_monptr = (-1);
  2408.         update_mon((int)cave[y][x].cptr);
  2409.         break;
  2410.       case 62:
  2411.         if (!blind)
  2412.         (void)strcat(cdesc, "magically summons Spiders.");
  2413.         else
  2414.         (void)strcat(cdesc, "mumbles, and you hear many things appear nearby.");
  2415.         msg_print(cdesc);
  2416.         y = char_row;
  2417.         x = char_col;
  2418.     /* in case compact_monster() is called,it needs monptr */
  2419.         for (k = 0; k < 6; k++) {
  2420.         hack_monptr = monptr;
  2421.         (void)summon_spider(&y, &x);
  2422.         hack_monptr = (-1);
  2423.         update_mon((int)cave[y][x].cptr);
  2424.         }
  2425.         break;
  2426.       case 63:
  2427.         if (!blind)
  2428.         (void)strcat(cdesc, "magically summons Hounds.");
  2429.         else
  2430.         (void)strcat(cdesc, "mumbles, and you hear many things appear nearby.");
  2431.         msg_print(cdesc);
  2432.         y = char_row;
  2433.         x = char_col;
  2434.     /* in case compact_monster() is called,it needs monptr */
  2435.         for (k = 0; k < 8; k++) {
  2436.         hack_monptr = monptr;
  2437.         (void)summon_hound(&y, &x);
  2438.         hack_monptr = (-1);
  2439.         update_mon((int)cave[y][x].cptr);
  2440.         }
  2441.         break;
  2442.       case 64:
  2443.         if (!blind)
  2444.         (void)strcat(cdesc, "breathes Nexus.");
  2445.         else
  2446.         (void)strcat(cdesc, "breathes, and you feel strange.");
  2447.         msg_print(cdesc);
  2448.         breath(GF_NEXUS, char_row, char_col,
  2449.         ((m_ptr->hp / 3) > 250 ? 250 : (m_ptr->hp / 3)), ddesc, monptr);
  2450.         break;
  2451.       case 65:
  2452.         if (!blind)
  2453.         (void)strcat(cdesc, "breathes elemental force.");
  2454.         else
  2455.         (void)strcat(cdesc, "breathes, and you are hit hard.");
  2456.         msg_print(cdesc);
  2457.         if (randint(10) == 1)
  2458.         br_wall(m_ptr->fy, m_ptr->fx);
  2459.         else
  2460.         breath(GF_FORCE, char_row, char_col,
  2461.                ((m_ptr->hp / 6) > 200 ? 200 : (m_ptr->hp / 6)),
  2462.                ddesc, monptr);
  2463.         break;
  2464.       case 66:
  2465.         if (!blind)
  2466.         (void)strcat(cdesc, "breathes inertia.");
  2467.         else
  2468.         (void)strcat(cdesc, "breathes.");
  2469.         msg_print(cdesc);
  2470.         breath(GF_INERTIA, char_row, char_col,
  2471.         ((m_ptr->hp / 6) > 200 ? 200 : (m_ptr->hp / 6)), ddesc, monptr);
  2472.         break;
  2473.       case 67:
  2474.         if (!blind)
  2475.         (void)strcat(cdesc, "breathes light.");
  2476.         else
  2477.         (void)strcat(cdesc, "breathes.");
  2478.         msg_print(cdesc);
  2479.         breath(GF_LIGHT, char_row, char_col,
  2480.         ((m_ptr->hp / 6) > 400 ? 400 : (m_ptr->hp / 6)), ddesc, monptr);
  2481.         break;
  2482.       case 68:
  2483.         if (!blind)
  2484.         (void)strcat(cdesc, "breathes time.");
  2485.         else
  2486.         (void)strcat(cdesc, "breathes.");
  2487.         msg_print(cdesc);
  2488.         breath(GF_TIME, char_row, char_col,
  2489.         ((m_ptr->hp / 3) > 150 ? 150 : (m_ptr->hp / 3)), ddesc, monptr);
  2490.         break;
  2491.       case 69:           /* gravity */
  2492.         if (!blind)
  2493.         (void)strcat(cdesc, "breathes gravity.");
  2494.         else
  2495.         (void)strcat(cdesc, "breathes, and you feel heavy.");
  2496.         msg_print(cdesc);
  2497.         breath(GF_GRAVITY, char_row, char_col,
  2498.         ((m_ptr->hp / 3) > 200 ? 200 : (m_ptr->hp / 3)), ddesc, monptr);
  2499.         break;
  2500.       case 70:           /* darkness */
  2501.         if (!blind)
  2502.         (void)strcat(cdesc, "breathes darkness.");
  2503.         else
  2504.         (void)strcat(cdesc, "breathes.");
  2505.         msg_print(cdesc);
  2506.         breath(GF_DARK, char_row, char_col,
  2507.         ((m_ptr->hp / 6) > 400 ? 400 : (m_ptr->hp / 6)), ddesc, monptr);
  2508.         break;
  2509.       case 71:           /* plasma */
  2510.         if (!blind)
  2511.         (void)strcat(cdesc, "breathes plasma.");
  2512.         else
  2513.         (void)strcat(cdesc, "breathes.");
  2514.         msg_print(cdesc);
  2515.         breath(GF_PLASMA, char_row, char_col,
  2516.         ((m_ptr->hp / 6) > 150 ? 150 : (m_ptr->hp / 6)), ddesc, monptr);
  2517.         break;
  2518.       case 72:
  2519.         if (!blind) {
  2520.         (void)strcat(cdesc, "fires an arrow at you.");
  2521.         msg_print(cdesc);
  2522.         } else
  2523.         msg_print("You hear the 'twang' of a bowstring.");
  2524.         bolt(GF_ARROW, char_row, char_col,
  2525.          damroll(1, 6), ddesc, m_ptr, monptr);
  2526.         break;
  2527.       case 73:
  2528.         if (!blind)
  2529.         (void)strcat(cdesc, "magically summons mighty undead opponents.");
  2530.         else
  2531.         (void)strcat(cdesc, "mumbles, and you hear many creepy things appear.");
  2532.         msg_print(cdesc);
  2533.         y = char_row;
  2534.         x = char_col;
  2535.     /* in case compact_monster() is called, it needs monptr */
  2536.         for (k = 0; k < 10; k++) {
  2537.         hack_monptr = monptr;
  2538.         (void)summon_wraith(&y, &x);
  2539.         hack_monptr = (-1);
  2540.         update_mon((int)cave[y][x].cptr);
  2541.         }
  2542.         for (k = 0; k < 7; k++) {
  2543.         hack_monptr = monptr;
  2544.         (void)summon_gundead(&y, &x);
  2545.         hack_monptr = (-1);
  2546.         update_mon((int)cave[y][x].cptr);
  2547.         }
  2548.         break;
  2549.       case 74:           /* Big darkness storm */
  2550.         if (!blind)
  2551.         (void)strcat(cdesc, "casts a Darkness Storm.");
  2552.         else
  2553.         (void)strcat(cdesc, "mumbles powerfully.");
  2554.         msg_print(cdesc);
  2555.         breath(GF_DARK, char_row, char_col,
  2556.         ((m_ptr->hp / 6) > 500 ? 500 : (m_ptr->hp / 6)), ddesc, monptr);
  2557.         break;
  2558.       case 75:           /* Mana storm */
  2559.         if (!blind)
  2560.         (void)strcat(cdesc, "invokes a Mana Storm.");
  2561.         else
  2562.         (void)strcat(cdesc, "mumbles, and you are hit by a storm of power.");
  2563.         msg_print(cdesc);
  2564.         breath(GF_MANA, char_row, char_col,
  2565.            (c_list[m_ptr->mptr].level * 5) + damroll(10, 10),
  2566.            ddesc, monptr);
  2567.         break;
  2568.       case 76:           /* Summon reptiles */
  2569.         if (!blind)
  2570.         (void)strcat(cdesc, "magically summons reptiles.");
  2571.         else
  2572.         (void)strcat(cdesc, "mumbles, and you hear many things appear nearby.");
  2573.         msg_print(cdesc);
  2574.         y = char_row;
  2575.         x = char_col;
  2576.     /* in case compact_monster() is called, it needs monptr */
  2577.         for (k = 0; k < 8; k++) {
  2578.         hack_monptr = monptr;
  2579.         (void)summon_reptile(&y, &x);
  2580.         hack_monptr = (-1);
  2581.         update_mon((int)cave[y][x].cptr);
  2582.         }
  2583.         break;
  2584.       case 77:           /* Summon ants */
  2585.         if (!blind)
  2586.         (void)strcat(cdesc, "magically summons ants.");
  2587.         else
  2588.         (void)strcat(cdesc, "mumbles, and you hear many things appear nearby.");
  2589.         msg_print(cdesc);
  2590.         y = char_row;
  2591.         x = char_col;
  2592.     /* in case compact_monster() is called, it needs monptr */
  2593.         for (k = 0; k < 7; k++) {
  2594.         hack_monptr = monptr;
  2595.         (void)summon_ant(&y, &x);
  2596.         hack_monptr = (-1);
  2597.         update_mon((int)cave[y][x].cptr);
  2598.         }
  2599.         break;
  2600.       case 78:           /* Summon unique monsters */
  2601.         if (!blind)
  2602.         (void)strcat(cdesc, "summons special opponents!");
  2603.         else
  2604.         (void)strcat(cdesc,
  2605.                  "mumbles, and you're worried by the things you hear nearby.");
  2606.         msg_print(cdesc);
  2607.         y = char_row;
  2608.         x = char_col;
  2609.     /* in case compact_monster() is called, it needs monptr */
  2610.         for (k = 0; k < 5; k++) {
  2611.         hack_monptr = monptr;
  2612.         (void)summon_unique(&y, &x);
  2613.         hack_monptr = (-1);
  2614.         update_mon((int)cave[y][x].cptr);
  2615.         }
  2616.         for (k = 0; k < 4; k++) {
  2617.         hack_monptr = monptr;
  2618.         (void)summon_jabberwock(&y, &x);
  2619.         hack_monptr = (-1);
  2620.         update_mon((int)cave[y][x].cptr);
  2621.         }
  2622.         break;
  2623.       case 79:           /* Summon greater undead */
  2624.         if (!blind)
  2625.         (void)strcat(cdesc, "summons the DEAD!");
  2626.         else
  2627.         (void)strcat(cdesc, "mumbles, and a chill runs down your spine.");
  2628.         msg_print(cdesc);
  2629.         y = char_row;
  2630.         x = char_col;
  2631.     /* in case compact_monster() is called, it needs monptr */
  2632.         for (k = 0; k < 8; k++) {
  2633.         hack_monptr = monptr;
  2634.         (void)summon_gundead(&y, &x);
  2635.         hack_monptr = (-1);
  2636.         update_mon((int)cave[y][x].cptr);
  2637.         }
  2638.         break;
  2639.       case 80:           /* Summon ancient dragons */
  2640.         if (!blind)
  2641.         (void)strcat(cdesc, "summons ancient dragons.");
  2642.         else
  2643.         (void)strcat(cdesc, "mumbles, and you hear many huge things appear nearby.");
  2644.         msg_print(cdesc);
  2645.         y = char_row;
  2646.         x = char_col;
  2647.     /* in case compact_monster() is called, it needs monptr */
  2648.         for (k = 0; k < 5; k++) {
  2649.         hack_monptr = monptr;
  2650.         (void)summon_ancientd(&y, &x);
  2651.         hack_monptr = (-1);
  2652.         update_mon((int)cave[y][x].cptr);
  2653.         }
  2654.         break;
  2655.       default:
  2656.         if (k != 200)
  2657.         (void)strcat(cdesc, "casts a bugged spell.");
  2658.         else
  2659.         (void)strcat(cdesc, "had no spell to cast, tell someone NOW!");
  2660.         msg_print(cdesc);
  2661.     }
  2662.     /* End of spells                       */
  2663.     if ((m_ptr->ml)           /* this won't work if we've been moved, so... */
  2664.         ||(thrown_spell == 45) /* add teleport away, */
  2665.         ||(thrown_spell == 57) /* and teleport lv -CFT */
  2666.         ) {
  2667.         if (thrown_spell < 33)
  2668.         c_recall[m_ptr->mptr].r_spells |= 1L << (thrown_spell - 1);
  2669.         else if (thrown_spell < 65)
  2670.         c_recall[m_ptr->mptr].r_spells2 |= 1L << (thrown_spell - 33);
  2671.         else if (thrown_spell < 97)    /* in case of 200 for bugs... -CFT */
  2672.         c_recall[m_ptr->mptr].r_spells3 |= 1L << (thrown_spell - 65);
  2673.         if ((c_recall[m_ptr->mptr].r_spells & CS_FREQ) != CS_FREQ)
  2674.         c_recall[m_ptr->mptr].r_spells++;
  2675.         if (death && c_recall[m_ptr->mptr].r_deaths < MAX_SHORT)
  2676.         c_recall[m_ptr->mptr].r_deaths++;
  2677.     }
  2678.     }
  2679. }
  2680.  
  2681.  
  2682. /* Places creature adjacent to given location        -RAK-     */
  2683. /* Rats and Flys are fun!                     */
  2684. int 
  2685. multiply_monster(y, x, cr_index, monptr)
  2686. int y, x, cr_index, monptr;
  2687. {
  2688.     register int        i, j, k;
  2689.     register cave_type *c_ptr;
  2690.     int                 result;
  2691.  
  2692. #ifdef ATARIST_MWC
  2693.     int32u              holder;
  2694. #endif
  2695.  
  2696.     i = 0;
  2697.     do {
  2698.     j = y - 2 + randint(3);
  2699.     k = x - 2 + randint(3);
  2700.     /*
  2701.      * don't create a new creature on top of the old one, that causes
  2702.      * invincible/invisible creatures to appear 
  2703.      */
  2704.     if (in_bounds(j, k) && (j != y || k != x)) {
  2705.         c_ptr = &cave[j][k];
  2706.         if ((c_ptr->fval <= MAX_OPEN_SPACE) && (c_ptr->tptr == 0) &&
  2707.         (c_ptr->cptr != 1)) {
  2708.         if (c_ptr->cptr > 1) {    /* Creature there already?     */
  2709.         /* Some critters are cannibalistic!        */
  2710.             if ((c_list[cr_index].cmove & CM_EATS_OTHER)
  2711.         /* Check the experience level -CJS- */
  2712.             && c_list[cr_index].mexp >=
  2713.             c_list[m_list[c_ptr->cptr].mptr].mexp) {
  2714.             /* It ate an already processed monster.Handle normally. */
  2715.             if (monptr < c_ptr->cptr)
  2716.                 delete_monster((int)c_ptr->cptr);
  2717.             /*
  2718.              * If it eats this monster, an already processed mosnter
  2719.              * will take its place, causing all kinds of havoc. Delay
  2720.              * the kill a bit. 
  2721.              */
  2722.             else
  2723.                 fix1_delete_monster((int)c_ptr->cptr);
  2724.  
  2725.             /* in case compact_monster() is called,it needs monptr */
  2726.             hack_monptr = monptr;
  2727.             result = place_monster(j, k, cr_index, FALSE);
  2728.             hack_monptr = (-1);
  2729.             if (!result)
  2730.                 return FALSE;
  2731.             mon_tot_mult++;
  2732.             return check_mon_lite(j, k);
  2733.             }
  2734.         } else
  2735.         /* All clear,  place a monster      */
  2736.         {
  2737.         /* in case compact_monster() is called,it needs monptr */
  2738.             hack_monptr = monptr;
  2739.             result = place_monster(j, k, cr_index, FALSE);
  2740.             hack_monptr = (-1);
  2741.             if (!result)
  2742.             return FALSE;
  2743.             mon_tot_mult++;
  2744.             return check_mon_lite(j, k);
  2745.         }
  2746.         }
  2747.     }
  2748.     i++;
  2749.     }
  2750.     while (i <= 18);
  2751.     return FALSE;
  2752. }
  2753.  
  2754.  
  2755. /* Move the critters about the dungeon            -RAK-     */
  2756. static void 
  2757. mon_move(monptr, rcmove)
  2758. int                 monptr;
  2759. int32u             *rcmove;
  2760. {
  2761.     register int           i, j;
  2762.     int                    k, move_test, dir;
  2763.     register creature_type *r_ptr;
  2764.     register monster_type  *m_ptr;
  2765.     int                    mm[9];
  2766.     bigvtype               out_val, m_name;
  2767.  
  2768.     m_ptr = &m_list[monptr];
  2769.     r_ptr = &c_list[m_ptr->mptr];
  2770.  
  2771. /* reduce fear, tough monsters can unfear faster -CFT, hacked by DGK */
  2772.     if (m_ptr->monfear) {
  2773.     int t = (int)m_ptr->monfear;    /* use int so avoid unsigned wraparound -CFT */
  2774.     t -= randint(c_list[m_ptr->mptr].level / 10);
  2775.     if (t <= 0) {
  2776.         t = 0;
  2777.         if (m_ptr->ml && los(char_row, char_col, m_ptr->fy, m_ptr->fx)) {
  2778.         monster_name(m_name, m_ptr, r_ptr);
  2779.         sprintf(out_val, "%s recovers its courage.", m_name);
  2780.         msg_print(out_val);
  2781.         }
  2782.     }
  2783.     m_ptr->monfear = (int8u) t;
  2784.     }
  2785. /* Does the critter multiply?                   */
  2786.     if ((r_ptr->cmove & CM_MULTIPLY) && (MAX_MON_MULT >= mon_tot_mult) &&
  2787.     (((py.flags.rest != -1) && ((py.flags.rest % MON_MULT_ADJ) == 0)) ||
  2788.      ((py.flags.rest == -1) && (randint(MON_MULT_ADJ) == 1)))) {
  2789.     k = 0;
  2790.     for (i = (int)m_ptr->fy - 1; i <= (int)m_ptr->fy + 1; i++)
  2791.         for (j = (int)m_ptr->fx - 1; j <= (int)m_ptr->fx + 1; j++)
  2792.         if (in_bounds(i, j) && (cave[i][j].cptr > 1))
  2793.             k++;
  2794.     /* can't call randint with a value of zero, increment counter to allow
  2795.      * creature multiplication 
  2796.      */
  2797.     if (k == 0)
  2798.         k++;
  2799.     if ((k < 4) && (randint(k * MON_MULT_ADJ) == 1))
  2800.         if (multiply_monster((int)m_ptr->fy, (int)m_ptr->fx,
  2801.                  (int)m_ptr->mptr, monptr))
  2802.         *rcmove |= CM_MULTIPLY;
  2803.     }
  2804.     move_test = FALSE;
  2805.  
  2806. /* if in wall, must immediately escape to a clear area */
  2807.     if (!(r_ptr->cmove & CM_PHASE) &&
  2808.     (cave[m_ptr->fy][m_ptr->fx].fval >= MIN_CAVE_WALL)) {
  2809.  
  2810.     /* If the monster is already dead, don't kill it again! This can happen
  2811.      * for monsters moving faster than the player.  They will get multiple
  2812.      * moves, but should not if they die on the first move.  This is only a
  2813.      * problem for monsters stuck in rock.  
  2814.      */
  2815.     if (m_ptr->hp < 0)
  2816.         return;
  2817.     k = 0;
  2818.     dir = 1;
  2819.     /* note direction of for loops matches direction of keypad from 1 to 9 */
  2820.     /* do not allow attack against the player */
  2821.     for (i = m_ptr->fy + 1; i >= (int)(m_ptr->fy - 1); i--)
  2822.         for (j = m_ptr->fx - 1; j <= (int)(m_ptr->fx + 1); j++) {
  2823.         if ((dir != 5) && (cave[i][j].fval <= MAX_OPEN_SPACE)
  2824.             && (cave[i][j].cptr != 1))
  2825.             mm[k++] = dir;
  2826.         dir++;
  2827.         }
  2828.     if (k != 0) {
  2829.     /* put a random direction first */
  2830.         dir = randint(k) - 1;
  2831.         i = mm[0];
  2832.         mm[0] = mm[dir];
  2833.         mm[dir] = i;
  2834.         make_move(monptr, mm, rcmove);
  2835.     /* this can only fail if mm[0] has a rune of protection */
  2836.     }
  2837.  
  2838. /* if still in a wall, let it dig itself out, but also apply some more damage */
  2839.     if (cave[m_ptr->fy][m_ptr->fx].fval >= MIN_CAVE_WALL) {
  2840. /* in case the monster dies, may need to call fix1_delete_monster()
  2841.  * instead of delete_monsters() 
  2842.  */
  2843.         hack_monptr = monptr;
  2844.         i = mon_take_hit(monptr, damroll(8, 8), FALSE);
  2845.         hack_monptr = (-1);
  2846.         if (i >= 0)
  2847.         msg_print("You hear a scream muffled by rock!");
  2848.         else
  2849.         (void)twall((int)m_ptr->fy, (int)m_ptr->fx, 1, 0);
  2850.     }
  2851.     return;               /* monster movement finished */
  2852.     }
  2853. /* Creature is confused?  Chance it becomes un-confused  */
  2854.     else if (m_ptr->confused) {
  2855.     mm[0] = randint(9);
  2856.     mm[1] = randint(9);
  2857.     mm[2] = randint(9);
  2858.     mm[3] = randint(9);
  2859.     mm[4] = randint(9);
  2860. /* don't move him if he is not supposed to move! */
  2861.     if (!(r_ptr->cmove & CM_ATTACK_ONLY)) {
  2862.         *rcmove |= CM_ATTACK_ONLY;
  2863.         make_move(monptr, mm, rcmove);
  2864.     }
  2865.  
  2866. /* reduce conf, tough monsters can unconf faster -CFT */
  2867.     {            /* use int so avoid unsigned wraparound -CFT */
  2868.         int t = (int)m_ptr->confused;
  2869.  
  2870.         t -= randint(c_list[m_ptr->mptr].level / 10);
  2871.         if (t < 0)
  2872.         t = 0;
  2873.         m_ptr->confused = (int8u) t;
  2874.     }
  2875.     move_test = TRUE;
  2876.     }
  2877.  
  2878. /* Creature may cast a spell */
  2879.     else if (r_ptr->spells != 0) {
  2880.     mon_cast_spell(monptr, &move_test);
  2881.     }
  2882.     if (!move_test) {
  2883.     /* 75% random movement */
  2884.     if ((r_ptr->cmove & CM_75_RANDOM) && (randint(100) < 75)) {
  2885.         mm[0] = randint(9);
  2886.         mm[1] = randint(9);
  2887.         mm[2] = randint(9);
  2888.         mm[3] = randint(9);
  2889.         mm[4] = randint(9);
  2890.         *rcmove |= CM_75_RANDOM;
  2891.         make_move(monptr, mm, rcmove);
  2892.     }
  2893.     /* 40% random movement */
  2894.     else if ((r_ptr->cmove & CM_40_RANDOM) && (randint(100) < 40)) {
  2895.         mm[0] = randint(9);
  2896.         mm[1] = randint(9);
  2897.         mm[2] = randint(9);
  2898.         mm[3] = randint(9);
  2899.         mm[4] = randint(9);
  2900.         *rcmove |= CM_40_RANDOM;
  2901.         make_move(monptr, mm, rcmove);
  2902.     }
  2903.     /* 20% random movement */
  2904.     else if ((r_ptr->cmove & CM_20_RANDOM) && (randint(100) < 20)) {
  2905.         mm[0] = randint(9);
  2906.         mm[1] = randint(9);
  2907.         mm[2] = randint(9);
  2908.         mm[3] = randint(9);
  2909.         mm[4] = randint(9);
  2910.         *rcmove |= CM_20_RANDOM;
  2911.         make_move(monptr, mm, rcmove);
  2912.     }
  2913.     /* Normal movement */
  2914.     else if (r_ptr->cmove & CM_MOVE_NORMAL) {
  2915.         if (randint(200) == 1) {
  2916.         mm[0] = randint(9);
  2917.         mm[1] = randint(9);
  2918.         mm[2] = randint(9);
  2919.         mm[3] = randint(9);
  2920.         mm[4] = randint(9);
  2921.         } else
  2922.         get_moves(monptr, mm);
  2923.         *rcmove |= CM_MOVE_NORMAL;
  2924.         make_move(monptr, mm, rcmove);
  2925.     }
  2926.     /* Attack, but don't move */
  2927.     else if ((r_ptr->cmove & CM_ATTACK_ONLY) && (m_ptr->cdis < 2)) {
  2928.         *rcmove |= CM_ATTACK_ONLY;
  2929.         get_moves(monptr, mm);
  2930.         make_move(monptr, mm, rcmove);
  2931.     } else if ((r_ptr->cmove & CM_ALL_MV_FLAGS) == 0 &&
  2932.            (m_ptr->cdis < 2)) {
  2933.  
  2934.         /* little hack for Quylthulgs, so that will eventually notice
  2935.          * that they have no physical attacks */
  2936.         if (c_recall[m_ptr->mptr].r_attacks[0] < MAX_UCHAR)
  2937.         c_recall[m_ptr->mptr].r_attacks[0]++;
  2938.     }
  2939.     }
  2940. }
  2941.  
  2942.  
  2943. /* Creatures movement and attacking are done from here    -RAK-     */
  2944. void 
  2945. creatures(attack)
  2946. int attack;
  2947. {
  2948.     register int          i, k;
  2949.     register monster_type *m_ptr;
  2950.     recall_type           *r_ptr;
  2951.     int32u                notice, rcmove;
  2952.     int                   wake, ignore;
  2953.     vtype                 cdesc;
  2954.  
  2955. /* Process the monsters  */
  2956.     for (i = mfptr - 1; i >= MIN_MONIX && !death; i--) {
  2957.     m_ptr = &m_list[i];
  2958.     /* Get rid of an eaten/breathed on monster.  Note: Be sure not to process
  2959.      * this monster. This is necessary because we can't delete monsters while
  2960.      * scanning the m_list here. 
  2961.      */
  2962.     if (m_ptr->hp < 0) {
  2963.         check_unique(m_ptr);
  2964.         fix2_delete_monster(i);
  2965.         continue;
  2966.     }
  2967.     m_ptr->cdis = distance(char_row, char_col,
  2968.                    (int)m_ptr->fy, (int)m_ptr->fx);
  2969.     if (attack) {           /* Attack is argument passed to CREATURE */
  2970.         k = movement_rate(i);
  2971.         if (k <= 0)
  2972.         update_mon(i);
  2973.         else
  2974.         while (k > 0) {
  2975.             k--;
  2976.             wake = FALSE;
  2977.             ignore = FALSE;
  2978.             rcmove = 0;
  2979.             if ((m_ptr->ml && /* check los so telepathy won't wake lice -CFT */
  2980.              los(char_row, char_col, (int)m_ptr->fy, (int)m_ptr->fx)) ||
  2981.             (m_ptr->cdis <= c_list[m_ptr->mptr].aaf)
  2982.  
  2983.             /* Monsters trapped in rock must be given a turn also,
  2984.              * so that they will die/dig out immediately.  */
  2985. #ifdef ATARIST_MWC
  2986.             || ((!(c_list[m_ptr->mptr].cmove & (holder = CM_PHASE)))
  2987. #else
  2988.             || ((!(c_list[m_ptr->mptr].cmove & CM_PHASE))
  2989. #endif
  2990.              && cave[m_ptr->fy][m_ptr->fx].fval >= MIN_CAVE_WALL)) {
  2991.             if (m_ptr->csleep > 0)
  2992.                 if (py.flags.aggravate)
  2993.                 m_ptr->csleep = 0;
  2994.                 else if ((py.flags.rest == 0 &&
  2995.                       py.flags.paralysis < 1)
  2996.                      || (randint(50) == 1)) {
  2997.                 notice = randint(1024);
  2998.                 if ((notice * notice * notice) <=
  2999.                     (1L << (29 - py.misc.stl))) {
  3000.                     m_ptr->csleep -= (100 / m_ptr->cdis);
  3001.                     if (m_ptr->csleep > 0)
  3002.                     ignore = TRUE;
  3003.                     else {
  3004.                     wake = TRUE;
  3005.                     /* force it to be exactly zero */
  3006.                     m_ptr->csleep = 0;
  3007.                     }
  3008.                 }
  3009.                 }
  3010.             if (m_ptr->stunned != 0) {
  3011. /* NOTE: Balrog = 100*100 = 10000, it always recovers instantly */
  3012.                 if (randint(5000) < c_list[m_ptr->mptr].level
  3013.                 * c_list[m_ptr->mptr].level)
  3014.                 m_ptr->stunned = 0;
  3015.                 else
  3016.                 m_ptr->stunned--;
  3017.                 if (m_ptr->stunned == 0) {
  3018.                 if (!m_ptr->ml)
  3019.                     (void)strcpy(cdesc, "It ");
  3020.                 else if (c_list[m_ptr->mptr].cdefense & UNIQUE)
  3021.                     (void)sprintf(cdesc, "%s ",
  3022.                           c_list[m_ptr->mptr].name);
  3023.                 else
  3024.                     (void)sprintf(cdesc, "The %s ",
  3025.                           c_list[m_ptr->mptr].name);
  3026.                 msg_print(strcat(cdesc,
  3027.                         "recovers and glares at you."));
  3028.                 }
  3029.             }
  3030.             if ((m_ptr->csleep == 0) && (m_ptr->stunned == 0))
  3031.                 mon_move(i, &rcmove);
  3032.             }
  3033.             update_mon(i);
  3034.             if (m_ptr->ml) {
  3035.             r_ptr = &c_recall[m_ptr->mptr];
  3036.             if (wake) {
  3037.                 if (r_ptr->r_wake < MAX_UCHAR)
  3038.                 r_ptr->r_wake++;
  3039.             } else if (ignore) {
  3040.                 if (r_ptr->r_ignore < MAX_UCHAR)
  3041.                 r_ptr->r_ignore++;
  3042.             }
  3043.             r_ptr->r_cmove |= rcmove;
  3044.             }
  3045.         }
  3046.     } else
  3047.         update_mon(i);
  3048.  
  3049.     /* Get rid of an eaten/breathed on monster.  This is necessary because we
  3050.      * can't delete monsters while scanning the m_list here.  This monster
  3051.      * may have been killed during mon_move(). 
  3052.      */
  3053.     if (m_ptr->hp < 0) {
  3054.         check_unique(m_ptr);
  3055.         fix2_delete_monster(i);
  3056.         continue;
  3057.     }
  3058.     }
  3059. /* End processing monsters       */
  3060. }
  3061.  
  3062. /* This is a fun one.  In a given block, pick some walls and     */
  3063. /* turn them into open spots.  Pick some open spots and turn     */
  3064. /* them into walls.  An "Earthquake" effect.           -LVB-   */
  3065. static void 
  3066. shatter_quake(mon_y, mon_x)
  3067. int mon_y, mon_x;
  3068. {
  3069.     register int           i, j, k, l;
  3070.     register cave_type     *c_ptr;
  3071.     register monster_type  *m_ptr;
  3072.     register creature_type *r_ptr;
  3073.     int                    kill, damage = 0, tmp, y, x = 0;
  3074.     vtype                  out_val, m_name;
  3075.     int                    monptr = cave[mon_y][mon_x].cptr;
  3076.     /* needed when we kill another monster */
  3077.  
  3078.     for (i = mon_y - 8; i <= mon_y + 8; i++)
  3079.     for (j = mon_x - 8; j <= mon_x + 8; j++)
  3080.         if (in_bounds(i, j) && (randint(8) == 1)) {
  3081.         if ((i == mon_y) && (j == mon_x))
  3082.             continue;
  3083.         c_ptr = &cave[i][j];
  3084.         if (c_ptr->cptr > 1) {
  3085.             m_ptr = &m_list[c_ptr->cptr];
  3086.             r_ptr = &c_list[m_ptr->mptr];
  3087.  
  3088.             if (!(r_ptr->cmove & CM_PHASE) &&
  3089.             !(r_ptr->cdefense & BREAK_WALL)) {
  3090.             if ((movement_rate(c_ptr->cptr) == 0) ||
  3091.                 (r_ptr->cmove & CM_ATTACK_ONLY))
  3092.             /* monster can not move to escape the wall */
  3093.                 kill = TRUE;
  3094.             else {
  3095. /* only kill if there is nowhere for the monster to escape to */
  3096.                 kill = TRUE;
  3097.                 for (y = i - 1; y <= i + 1; y++) {
  3098.                 for (x = j - 1; x <= j + 1; x++) {
  3099.                     if ((cave[y][x].fval <= MAX_OPEN_SPACE) &&
  3100.                     !(y == i && x == j)) {
  3101.                     kill = FALSE;
  3102.                     break;
  3103.                     }
  3104.                 }
  3105.                 if (!kill)
  3106.                     break;
  3107.                 }
  3108.             }
  3109.             if (kill)
  3110.                 damage = 0x7fff;    /* this will kill everything */
  3111.             else
  3112.                 damage = damroll(4, 8);
  3113.             monster_name(m_name, m_ptr, r_ptr);
  3114.             (void)sprintf(out_val, "%s wails out in pain!", m_name);
  3115.             msg_print(out_val);
  3116.             /* kill monster "by hand", so player doesn't get exp -CFT */
  3117.             m_ptr->hp = m_ptr->hp - damage;
  3118.             m_ptr->csleep = 0;
  3119.  
  3120. /* prevent unique monster from death by other monsters.  It causes trouble
  3121.  * (monster not marked as dead, quest monsters don't satisfy quest, etc).
  3122.  * So, we let then live, but extremely wimpy.  This isn't great, because
  3123.  * monster might heal itself before player's next swing... -CFT
  3124.  */
  3125.             if ((r_ptr->cdefense & UNIQUE) && (m_ptr->hp < 0))
  3126.                 m_ptr->hp = 0;
  3127.             if (m_ptr->hp < 0) {
  3128.                 int32u              temp, treas;
  3129.  
  3130.                 (void)sprintf(out_val, "%s is embedded in the rock.",
  3131.                       m_name);
  3132.                 msg_print(out_val);
  3133.                 object_level = (dun_level + r_ptr->level) >> 1;
  3134.                 treas = monster_death((int)m_ptr->fy, (int)m_ptr->fx,
  3135.                           r_ptr->cmove, 0, 0);
  3136.                 if (m_ptr->ml) {
  3137.                 temp = (c_recall[m_ptr->mptr].r_cmove & CM_TREASURE)
  3138.                     >> CM_TR_SHIFT;
  3139.                 if (temp > ((treas & CM_TREASURE) >> CM_TR_SHIFT))
  3140.                     treas = (treas & ~CM_TREASURE) | (temp << CM_TR_SHIFT);
  3141.                 c_recall[m_ptr->mptr].r_cmove = treas |
  3142.                     (c_recall[m_ptr->mptr].r_cmove & ~CM_TREASURE);
  3143.                 }
  3144.                 if (monptr < c_ptr->cptr)
  3145.                 delete_monster((int)c_ptr->cptr);
  3146.                 else
  3147.                 fix1_delete_monster((int)c_ptr->cptr);
  3148.             } /* if monster's hp < 0 */
  3149.             }
  3150.         } else if (c_ptr->cptr == 1) {    /* Kill the dumb player! */
  3151.             kill = TRUE;
  3152.             for (y = i - 1; y <= i + 1; y++) {
  3153.             for (x = j - 1; x <= j + 1; x++) {
  3154.                 if ((cave[y][x].fval <= MAX_OPEN_SPACE) &&
  3155.                 (cave[y][x].cptr == 0) && !(y == i && x == j)) {
  3156.                 kill = FALSE;
  3157.                 break;
  3158.                 }
  3159.             }
  3160.             if (!kill)
  3161.                 break;
  3162.             }
  3163.  
  3164.             switch (randint(3)) {
  3165.               case 1:
  3166.             msg_print("The cave ceiling collapses!");
  3167.             break;
  3168.               case 2:
  3169.             msg_print("The floor turns and crushes you!");
  3170.             break;
  3171.               case 3:
  3172.             msg_print("You are pummeled with debris!");
  3173.             break;
  3174.             }
  3175.             if (kill) {
  3176.     msg_print("You are trapped and cannot move!  You are crushed beneath rock!");
  3177.     msg_print(NULL);
  3178.             damage = 320;
  3179.             } else {
  3180.             switch (randint(3)) {
  3181.               case 1:
  3182.                 msg_print("The rubble bashes you!");
  3183.                 damage = damroll(10, 4);
  3184.                 stun_player(randint(50));
  3185.                 break;
  3186.               case 2:
  3187.                 msg_print("But you nimbly dodge the blast!");
  3188.                 damage = 0;
  3189.                 break;
  3190.               case 3:
  3191.                 msg_print("The floor crushes you against the ceiling!");
  3192.                 damage = damroll(10, 4);
  3193.                 stun_player(randint(50));
  3194.                 break;
  3195.             }
  3196.             move_rec(char_row, char_col, y, x);
  3197.             for (k = char_row - 1; k <= char_row + 1; k++)
  3198.                 for (l = char_col - 1; l <= char_col + 1; l++) {
  3199.                 c_ptr = &cave[k][l];
  3200.                 c_ptr->tl = FALSE;
  3201.                 lite_spot(k, l);
  3202.                 }
  3203.             lite_spot(char_row, char_col);
  3204.             char_row = y;
  3205.             char_col = x;
  3206.             check_view();
  3207.             /* light creatures */
  3208.             creatures(FALSE);
  3209.             }
  3210.             take_hit(damage, "an Earthquake");
  3211.         }
  3212.         if (c_ptr->tptr != 0)
  3213.             if (((t_list[c_ptr->tptr].tval >= TV_MIN_WEAR) &&
  3214.              (t_list[c_ptr->tptr].tval <= TV_MAX_WEAR) &&
  3215.              (t_list[c_ptr->tptr].flags2 & TR_ARTIFACT)) ||
  3216.             (t_list[c_ptr->tptr].tval == TV_UP_STAIR) ||
  3217.             (t_list[c_ptr->tptr].tval == TV_DOWN_STAIR) ||
  3218.             (t_list[c_ptr->tptr].tval == TV_STORE_DOOR))
  3219.             continue;  /* don't kill artifacts... */
  3220.             else
  3221.             (void)delete_object(i, j);
  3222.  
  3223.         if ((c_ptr->fval >= MIN_CAVE_WALL) && (c_ptr->fval != BOUNDARY_WALL)) {
  3224.             c_ptr->fval = CORR_FLOOR;
  3225.             c_ptr->pl = FALSE;
  3226.             c_ptr->fm = FALSE;
  3227.         } else if ((c_ptr->fval <= MAX_CAVE_FLOOR) && (c_ptr->tptr == 0)
  3228.                && (c_ptr->cptr != 1)) {
  3229.             /* don't bury player, it made him unattackable -CFT */
  3230.             tmp = randint(10);
  3231.             if (tmp < 6)
  3232.             c_ptr->fval = QUARTZ_WALL;
  3233.             else if (tmp < 9)
  3234.             c_ptr->fval = MAGMA_WALL;
  3235.             else
  3236.             c_ptr->fval = GRANITE_WALL;
  3237.  
  3238.             c_ptr->fm = FALSE;
  3239.         }
  3240.         lite_spot(i, j);
  3241.         }
  3242. }
  3243.  
  3244. /* This is a fun one.  In a given block, pick some walls and     */
  3245. /* turn them into open spots.  Pick some open spots and turn     */
  3246. /* them into walls.  An "Earthquake" effect.           -LVB-   */
  3247. static void 
  3248. br_wall(mon_y, mon_x)
  3249. int mon_y, mon_x;
  3250. {
  3251.     register int        k, l;
  3252.     register cave_type *c_ptr;
  3253.     int                 kill, damage = 0, tmp, y, x = 0;
  3254.  
  3255.     kill = TRUE;
  3256.     for (y = char_row - 1; y <= char_row + 1; y++) {
  3257.     for (x = char_col - 1; x <= char_col + 1; x++) {
  3258.         if ((cave[y][x].fval <= MAX_OPEN_SPACE) &&
  3259.           (cave[y][x].cptr == 0) && !(y == char_row && x == char_col)) {
  3260.         kill = FALSE;
  3261.         break;
  3262.         }
  3263.     }
  3264.     if (!kill)
  3265.         break;
  3266.     }
  3267.  
  3268.     switch (randint(3)) {
  3269.       case 1:
  3270.     msg_print("The cave ceiling collapses!");
  3271.     break;
  3272.       case 2:
  3273.     msg_print("The floor turns and crushes you!");
  3274.     break;
  3275.       case 3:
  3276.     msg_print("You are pummeled with debris!");
  3277.     break;
  3278.     }
  3279.     if (kill) {
  3280.     msg_print("You are trapped, crushed and cannot move!");
  3281.     damage = 250;
  3282.     } else {
  3283.     switch (randint(3)) {
  3284.       case 1:
  3285.         msg_print("The rubble bashes you!");
  3286.         damage = damroll(10, 4);
  3287.         stun_player(randint(50));
  3288.         break;
  3289.       case 2:
  3290.         msg_print("But you nimbly dodge the blast!");
  3291.         damage = 0;
  3292.         break;
  3293.       case 3:
  3294.         msg_print("The floor crushes you against the ceiling!");
  3295.         damage = damroll(10, 4);
  3296.         stun_player(randint(50));
  3297.         break;
  3298.     }
  3299.     c_ptr = &cave[char_row][char_col];
  3300.     move_rec(char_row, char_col, y, x);
  3301.     /* don't destroy floor if stairs, shop, or artifact... */
  3302.     if ((c_ptr->fval <= MAX_CAVE_FLOOR) &&
  3303.     ((c_ptr->tptr == 0) || ((t_list[c_ptr->tptr].tval != TV_UP_STAIR) &&
  3304.                   (t_list[c_ptr->tptr].tval != TV_DOWN_STAIR) &&
  3305.                   (t_list[c_ptr->tptr].tval != TV_STORE_DOOR) &&
  3306.                   !((t_list[c_ptr->tptr].tval >= TV_MIN_WEAR) &&
  3307.                 (t_list[c_ptr->tptr].tval <= TV_MAX_WEAR) &&
  3308.                 (t_list[c_ptr->tptr].flags2 & TR_ARTIFACT))))) {
  3309.         if (c_ptr->tptr)
  3310.         delete_object(char_row, char_col);
  3311.         tmp = randint(10);
  3312.         if (tmp < 6)
  3313.         c_ptr->fval = QUARTZ_WALL;
  3314.         else if (tmp < 9)
  3315.         c_ptr->fval = MAGMA_WALL;
  3316.         else
  3317.         c_ptr->fval = GRANITE_WALL;
  3318.  
  3319.         c_ptr->fm = FALSE;
  3320.     }
  3321.     for (k = char_row - 1; k <= char_row + 1; k++)
  3322.         for (l = char_col - 1; l <= char_col + 1; l++) {
  3323.         c_ptr = &cave[k][l];
  3324.         c_ptr->tl = FALSE;
  3325.         lite_spot(k, l);
  3326.         }
  3327.     lite_spot(char_row, char_col);
  3328.     char_row = y;
  3329.     char_col = x;
  3330.     } /* !kill */
  3331.     check_view();
  3332. /* light creatures */
  3333.     creatures(FALSE);
  3334.     lite_spot(char_row, char_col);
  3335.     take_hit(damage, "an Earthquake");
  3336. }
  3337.